Просмотр исходного кода

Merge remote-tracking branch 'origin/develop' into xap

QMK Bot 1 год назад
Родитель
Сommit
0402213d51
61 измененных файлов с 638 добавлено и 661 удалено
  1. 1 1
      builddefs/common_features.mk
  2. 38 7
      docs/drivers/ws2812.md
  3. 15 0
      drivers/ws2812.c
  4. 32 13
      drivers/ws2812.h
  5. 2 0
      keyboards/1k/config.h
  6. 2 2
      keyboards/1k/keymaps/default/rgblite.h
  7. 2 0
      keyboards/ergodox_ez/post_config.h
  8. 45 37
      keyboards/ergodox_ez/shine/rgblight_custom.c
  9. 1 0
      keyboards/handwired/promethium/config.h
  10. 2 6
      keyboards/handwired/promethium/rgbsps.c
  11. 1 0
      keyboards/ibm/model_m/mschwingen/config.h
  12. 35 30
      keyboards/ibm/model_m/mschwingen/mschwingen.c
  13. 4 0
      keyboards/input_club/ergodox_infinity/ergodox_infinity.c
  14. 4 0
      keyboards/keychron/q11/ansi_encoder/ansi_encoder.c
  15. 4 0
      keyboards/keychron/q11/iso_encoder/iso_encoder.c
  16. 3 3
      keyboards/kprepublic/bm60hsrgb/rev2/config.h
  17. 8 18
      keyboards/kprepublic/bm60hsrgb/rev2/rev2.c
  18. 3 3
      keyboards/kprepublic/bm60hsrgb_iso/rev2/config.h
  19. 8 18
      keyboards/kprepublic/bm60hsrgb_iso/rev2/rev2.c
  20. 3 3
      keyboards/kprepublic/bm60hsrgb_poker/rev2/config.h
  21. 8 18
      keyboards/kprepublic/bm60hsrgb_poker/rev2/rev2.c
  22. 23 22
      keyboards/matrix/abelx/abelx.c
  23. 1 0
      keyboards/matrix/abelx/config.h
  24. 0 7
      keyboards/matrix/m20add/m20add.c
  25. 6 13
      keyboards/matrix/m20add/rgb_ring.c
  26. 0 1
      keyboards/matrix/m20add/rgb_ring.h
  27. 1 1
      keyboards/matrix/noah/keyboard.json
  28. 0 57
      keyboards/matrix/noah/noah.c
  29. 33 28
      keyboards/neson_design/700e/700e.c
  30. 1 0
      keyboards/neson_design/700e/config.h
  31. 1 0
      keyboards/neson_design/n6/config.h
  32. 34 27
      keyboards/neson_design/n6/n6.c
  33. 17 4
      keyboards/oddforge/vea/ws2812_custom.c
  34. 3 0
      keyboards/orthograph/orthograph.c
  35. 1 0
      keyboards/rgbkb/pan/config.h
  36. 4 24
      keyboards/rgbkb/pan/pan.c
  37. 40 20
      keyboards/steelseries/prime_plus/rgblight_custom.c
  38. 6 12
      keyboards/wilba_tech/wt_rgb_backlight.c
  39. 7 3
      keyboards/work_louder/rgb_functions.c
  40. 1 1
      keyboards/xelus/dawn60/rev1/config.h
  41. 2 2
      keyboards/xelus/dawn60/rev1_qmk/config.h
  42. 3 11
      keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c
  43. 3 0
      keyboards/xiudi/xd002/keymaps/rgb_lite/config.h
  44. 3 3
      keyboards/xiudi/xd002/keymaps/rgb_lite/rgblite.h
  45. 30 22
      platforms/avr/drivers/ws2812_bitbang.c
  46. 19 3
      platforms/avr/drivers/ws2812_i2c.c
  47. 22 5
      platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c
  48. 29 13
      platforms/chibios/drivers/ws2812_bitbang.c
  49. 22 6
      platforms/chibios/drivers/ws2812_pwm.c
  50. 21 4
      platforms/chibios/drivers/ws2812_spi.c
  51. 0 11
      quantum/color.c
  52. 0 24
      quantum/color.h
  53. 10 1
      quantum/led_matrix/led_matrix.c
  54. 2 0
      quantum/led_matrix/led_matrix.h
  55. 10 1
      quantum/rgb_matrix/rgb_matrix.c
  56. 2 0
      quantum/rgb_matrix/rgb_matrix.h
  57. 4 54
      quantum/rgb_matrix/rgb_matrix_drivers.c
  58. 45 107
      quantum/rgblight/rgblight.c
  59. 0 1
      quantum/rgblight/rgblight.h
  60. 8 12
      quantum/rgblight/rgblight_drivers.c
  61. 3 2
      quantum/rgblight/rgblight_drivers.h

+ 1 - 1
builddefs/common_features.mk

@@ -952,7 +952,7 @@ ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
 
 
     OPT_DEFS += -DWS2812_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]'))
     OPT_DEFS += -DWS2812_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]'))
 
 
-    SRC += ws2812_$(strip $(WS2812_DRIVER)).c
+    SRC += ws2812.c ws2812_$(strip $(WS2812_DRIVER)).c
 
 
     ifeq ($(strip $(PLATFORM)), CHIBIOS)
     ifeq ($(strip $(PLATFORM)), CHIBIOS)
         ifeq ($(strip $(WS2812_DRIVER)), pwm)
         ifeq ($(strip $(WS2812_DRIVER)), pwm)

+ 38 - 7
docs/drivers/ws2812.md

@@ -241,13 +241,44 @@ Using a complementary timer output (`TIMx_CHyN`) is possible only for advanced-c
 
 
 ## API {#api}
 ## API {#api}
 
 
-### `void ws2812_setleds(rgb_led_t *ledarray, uint16_t number_of_leds)` {#api-ws2812-setleds}
+### `void ws2812_init(void)` {#api-ws2812-init}
 
 
-Send RGB data to the WS2812 LED chain.
+Initialize the LED driver. This function should be called first.
 
 
-#### Arguments {#api-ws2812-setleds-arguments}
+---
 
 
- - `rgb_led_t *ledarray`  
-   A pointer to the LED array.
- - `uint16_t number_of_leds`  
-   The length of the LED array.
+### `void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-ws2812-set-color}
+
+Set the color of a single LED. This function does not immediately update the LEDs; call `ws2812_flush()` after you are finished.
+
+#### Arguments {#api-ws2812-set-color-arguments}
+
+ - `int index`  
+   The LED index in the WS2812 chain.
+ - `uint8_t red`  
+   The red value to set.
+ - `uint8_t green`  
+   The green value to set.
+ - `uint8_t blue`  
+   The blue value to set.
+
+---
+
+### `void ws812_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-ws2812-set-color-all}
+
+Set the color of all LEDs.
+
+#### Arguments {#api-ws2812-set-color-all-arguments}
+
+ - `uint8_t red`  
+   The red value to set.
+ - `uint8_t green`  
+   The green value to set.
+ - `uint8_t blue`  
+   The blue value to set.
+
+---
+
+### `void ws2812_flush(void)` {#api-ws2812-flush}
+
+Flush the PWM values to the LED chain.

+ 15 - 0
drivers/ws2812.c

@@ -0,0 +1,15 @@
+// Copyright 2024 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "ws2812.h"
+
+#if defined(WS2812_RGBW)
+void ws2812_rgb_to_rgbw(ws2812_led_t *led) {
+    // Determine lowest value in all three colors, put that into
+    // the white channel and then shift all colors by that amount
+    led->w = MIN(led->r, MIN(led->g, led->b));
+    led->r -= led->w;
+    led->g -= led->w;
+    led->b -= led->w;
+}
+#endif

+ 32 - 13
drivers/ws2812.h

@@ -15,7 +15,7 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "quantum/color.h"
+#include "util.h"
 
 
 /*
 /*
  * The WS2812 datasheets define T1H 900ns, T0H 350ns, T1L 350ns, T0L 900ns. Hence, by default, these
  * The WS2812 datasheets define T1H 900ns, T0H 350ns, T1L 350ns, T0L 900ns. Hence, by default, these
@@ -62,17 +62,36 @@
 #    define WS2812_LED_COUNT RGB_MATRIX_LED_COUNT
 #    define WS2812_LED_COUNT RGB_MATRIX_LED_COUNT
 #endif
 #endif
 
 
+#define WS2812_BYTE_ORDER_RGB 0
+#define WS2812_BYTE_ORDER_GRB 1
+#define WS2812_BYTE_ORDER_BGR 2
+
+#ifndef WS2812_BYTE_ORDER
+#    define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB
+#endif
+
+typedef struct PACKED ws2812_led_t {
+#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
+    uint8_t g;
+    uint8_t r;
+    uint8_t b;
+#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
+    uint8_t r;
+    uint8_t g;
+    uint8_t b;
+#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
+    uint8_t b;
+    uint8_t g;
+    uint8_t r;
+#endif
+#ifdef WS2812_RGBW
+    uint8_t w;
+#endif
+} ws2812_led_t;
+
 void ws2812_init(void);
 void ws2812_init(void);
+void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
+void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
+void ws2812_flush(void);
 
 
-/* User Interface
- *
- * Input:
- *         ledarray:           An array of GRB data describing the LED colors
- *         number_of_leds:     The number of LEDs to write
- *
- * The functions will perform the following actions:
- *         - Set the data-out pin as output
- *         - Send out the LED data
- *         - Wait 50us to reset the LEDs
- */
-void ws2812_setleds(rgb_led_t *ledarray, uint16_t number_of_leds);
+void ws2812_rgb_to_rgbw(ws2812_led_t *led);

+ 2 - 0
keyboards/1k/config.h

@@ -32,3 +32,5 @@
 #define USB_INTR_ENABLE_BIT PCIE
 #define USB_INTR_ENABLE_BIT PCIE
 #define USB_INTR_PENDING_BIT PCIF
 #define USB_INTR_PENDING_BIT PCIF
 #define USB_INTR_VECTOR SIG_PIN_CHANGE
 #define USB_INTR_VECTOR SIG_PIN_CHANGE
+
+#define WS2812_LED_COUNT 1

+ 2 - 2
keyboards/1k/keymaps/default/rgblite.h

@@ -11,8 +11,8 @@ static inline void rgblite_init(void) {
 }
 }
 
 
 static inline void rgblite_setrgb(RGB rgb) {
 static inline void rgblite_setrgb(RGB rgb) {
-    rgb_led_t leds[RGBLIGHT_LED_COUNT] = {{.r = rgb.r, .g = rgb.g, .b = rgb.b}};
-    ws2812_setleds(leds, RGBLIGHT_LED_COUNT);
+    ws2812_set_color_all(rgb.r, rgb.g, rgb.b);
+    ws2812_flush();
 }
 }
 
 
 static void rgblite_increase_hue(void) {
 static void rgblite_increase_hue(void) {

+ 2 - 0
keyboards/ergodox_ez/post_config.h

@@ -33,8 +33,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 #ifdef ERGODOX_LED_30
 #ifdef ERGODOX_LED_30
 // If using 30 LEDs, then define that many
 // If using 30 LEDs, then define that many
+#    define WS2812_LED_COUNT 30
 #    define RGBLIGHT_LED_COUNT 30  // Number of LEDs
 #    define RGBLIGHT_LED_COUNT 30  // Number of LEDs
 #else
 #else
 // If not, then only define 15
 // If not, then only define 15
+#    define WS2812_LED_COUNT 15
 #    define RGBLIGHT_LED_COUNT 15  // Number of LEDs
 #    define RGBLIGHT_LED_COUNT 15  // Number of LEDs
 #endif
 #endif

+ 45 - 37
keyboards/ergodox_ez/shine/rgblight_custom.c

@@ -21,47 +21,55 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "ergodox_ez.h"
 #include "ergodox_ez.h"
 #include "ws2812.h"
 #include "ws2812.h"
 
 
-void setleds_custom(rgb_led_t *led, uint16_t led_num) {
-    uint16_t length = 0;
-    int i = 0;
-    int j = 0;
-#    ifdef WS2812_RGBW
-    int bytes_per_led = 4;
-#    else
-    int bytes_per_led = 3;
-#    endif
-#    if defined(ERGODOX_LED_30)
-    // prevent right-half code from trying to bitbang all 30
-    // so with 30 LEDs, we count from 29 to 15 here, and the
-    // other half does 0 to 14.
-    uint8_t half_led_num = RGBLIGHT_LED_COUNT / 2;
-    length = half_led_num * bytes_per_led;
-    uint8_t data[length];
-    for (i = half_led_num + half_led_num - 1; i >= half_led_num; --i)
-#    elif defined(ERGODOX_LED_15_MIRROR)
-    length = led_num * bytes_per_led;
-    uint8_t data[length];
-    for (i = 0; i < led_num; ++i)
-#    else  // ERGDOX_LED_15 non-mirrored
-    length = led_num * bytes_per_led;
-    uint8_t data[length];
-    for (i = led_num - 1; i >= 0; --i)
-#    endif
-    {
-        uint8_t *data_byte = (uint8_t *)(led + i);
-        data[j++] = data_byte[0];
-        data[j++] = data_byte[1];
-        data[j++] = data_byte[2];
-#ifdef WS2812_RGBW
-        data[j++] = data_byte[3];
+#define WS2812_I2C_ADDRESS_LEFT 0x84
+
+#if defined(ERGODOX_LED_30)
+#    define WS2812_LED_COUNT_LEFT (RGBLIGHT_LED_COUNT / 2)
+ws2812_led_t ws2812_leds_left[WS2812_LED_COUNT_LEFT];
+#else
+#    define WS2812_LED_COUNT_LEFT RGBLIGHT_LED_COUNT
+ws2812_led_t ws2812_leds_left[WS2812_LED_COUNT_LEFT];
+#endif
+
+void set_color_left(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    ws2812_leds_left[index].r = red;
+    ws2812_leds_left[index].g = green;
+    ws2812_leds_left[index].b = blue;
+#if defined(WS2812_RGBW)
+    ws2812_rgb_to_rgbw(&ws2812_leds_left[index]);
+#endif
+}
+
+void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) {
+#if defined(ERGODOX_LED_30)
+    if (index < WS2812_LED_COUNT_LEFT) {
+        ws2812_set_color(index, red, green, blue);
+    } else {
+        set_color_left(RGBLIGHT_LED_COUNT - index - 1, red, green, blue);
+    }
+#elif defined(ERGODOX_LED_15_MIRROR)
+    ws2812_set_color(index, red, green, blue);
+    set_color_left(index, red, green, blue);
+#else
+    ws2812_set_color(index, red, green, blue);
+    set_color_left(WS2812_LED_COUNT_LEFT - index - 1, red, green, blue);
 #endif
 #endif
+}
+
+void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) {
+        set_color_custom(i, red, green, blue);
     }
     }
-    i2c_transmit(0x84, data, sizeof(data), ERGODOX_EZ_I2C_TIMEOUT);
+}
 
 
-    ws2812_setleds(led, led_num);
+void flush_custom(void) {
+    i2c_transmit(WS2812_I2C_ADDRESS_LEFT, (uint8_t *)ws2812_leds_left, sizeof(ws2812_leds_left), ERGODOX_EZ_I2C_TIMEOUT);
+    ws2812_flush();
 }
 }
 
 
 const rgblight_driver_t rgblight_driver = {
 const rgblight_driver_t rgblight_driver = {
-    .init    = ws2812_init,
-    .setleds = setleds_custom,
+    .init          = ws2812_init,
+    .set_color     = set_color_custom,
+    .set_color_all = set_color_all_custom,
+    .flush         = flush_custom,
 };
 };

+ 1 - 0
keyboards/handwired/promethium/config.h

@@ -155,6 +155,7 @@ enum led_sequence {
 };
 };
 
 
 #    define RGBSPS_NUM LED_TOTAL
 #    define RGBSPS_NUM LED_TOTAL
+#    define WS2812_LED_COUNT RGBSPS_NUM
 #endif
 #endif
 
 
 /* PS/2 mouse */
 /* PS/2 mouse */

+ 2 - 6
keyboards/handwired/promethium/rgbsps.c

@@ -2,8 +2,6 @@
 #include "ws2812.h"
 #include "ws2812.h"
 #include "rgbsps.h"
 #include "rgbsps.h"
 
 
-rgb_led_t led[RGBSPS_NUM];
-
 void keyboard_pre_init_kb(void) {
 void keyboard_pre_init_kb(void) {
   ws2812_init();
   ws2812_init();
 
 
@@ -11,9 +9,7 @@ void keyboard_pre_init_kb(void) {
 }
 }
 
 
 void rgbsps_set(uint8_t index, uint8_t r, uint8_t g, uint8_t b) {
 void rgbsps_set(uint8_t index, uint8_t r, uint8_t g, uint8_t b) {
-  led[index].r = r;
-  led[index].g = g;
-  led[index].b = b;
+  ws2812_set_color(index, r, g, b);
 }
 }
 
 
 void rgbsps_setall(uint8_t r, uint8_t g, uint8_t b) {
 void rgbsps_setall(uint8_t r, uint8_t g, uint8_t b) {
@@ -27,7 +23,7 @@ void rgbsps_turnoff(void) {
 }
 }
 
 
 void rgbsps_send(void) {
 void rgbsps_send(void) {
-  ws2812_setleds(led, RGBSPS_NUM);
+  ws2812_flush();
 }
 }
 
 
 void rgbsps_sethsv(uint8_t index, uint16_t hue, uint8_t sat, uint8_t val) {
 void rgbsps_sethsv(uint8_t index, uint16_t hue, uint8_t sat, uint8_t val) {

+ 1 - 0
keyboards/ibm/model_m/mschwingen/config.h

@@ -65,6 +65,7 @@
 # define MODELM_LED_SCROLLOCK MODELM_LED3
 # define MODELM_LED_SCROLLOCK MODELM_LED3
 # define MODELM_LED_NUMLOCK   MODELM_LED1
 # define MODELM_LED_NUMLOCK   MODELM_LED1
 #elif defined(KEYBOARD_ibm_model_m_mschwingen_led_ws2812)
 #elif defined(KEYBOARD_ibm_model_m_mschwingen_led_ws2812)
+# define WS2812_LED_COUNT 3
 #else
 #else
 # error one of MODELM_LEDS_FFC, MODELM_LEDS_WIRED or MODELM_LEDS_WS2812 must be set!
 # error one of MODELM_LEDS_FFC, MODELM_LEDS_WIRED or MODELM_LEDS_WS2812 must be set!
 #endif
 #endif

+ 35 - 30
keyboards/ibm/model_m/mschwingen/mschwingen.c

@@ -39,27 +39,10 @@ static uint8_t  isRecording = 0;
 #    if RGBLIGHT_LED_COUNT < 3
 #    if RGBLIGHT_LED_COUNT < 3
 #        error we need at least 3 RGB LEDs!
 #        error we need at least 3 RGB LEDs!
 #    endif
 #    endif
-static rgb_led_t led[RGBLIGHT_LED_COUNT] = {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}};
 
 
 #    define BRIGHT 32
 #    define BRIGHT 32
 #    define DIM 6
 #    define DIM 6
 
 
-static const rgb_led_t black = {.r = 0, .g = 0, .b = 0};
-
-static const __attribute__((unused)) rgb_led_t green  = {.r = 0, .g = BRIGHT, .b = 0};
-static const __attribute__((unused)) rgb_led_t lgreen = {.r = 0, .g = DIM, .b = 0};
-
-static const __attribute__((unused)) rgb_led_t red  = {.r = BRIGHT, .g = 0, .b = 0};
-static const __attribute__((unused)) rgb_led_t lred = {.r = DIM, .g = 0, .b = 0};
-
-static const __attribute__((unused)) rgb_led_t blue  = {.r = 0, .g = 0, .b = BRIGHT};
-static const __attribute__((unused)) rgb_led_t lblue = {.r = 0, .g = 0, .b = DIM};
-
-static const __attribute__((unused)) rgb_led_t turq  = {.r = 0, .g = BRIGHT, .b = BRIGHT};
-static const __attribute__((unused)) rgb_led_t lturq = {.r = 0, .g = DIM, .b = DIM};
-
-static const __attribute__((unused)) rgb_led_t white = {.r = BRIGHT, .g = BRIGHT, .b = BRIGHT};
-
 static led_t   led_state;
 static led_t   led_state;
 static uint8_t layer;
 static uint8_t layer;
 static uint8_t default_layer;
 static uint8_t default_layer;
@@ -81,17 +64,15 @@ void sleep_led_enable(void) {
     suspend_active = true;
     suspend_active = true;
     gpio_write_pin_low(MODELM_STATUS_LED);
     gpio_write_pin_low(MODELM_STATUS_LED);
 #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
 #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
-    led[0] = black;
-    led[1] = black;
-    led[2] = black;
-    ws2812_setleds(led, RGBLIGHT_LED_COUNT);
+    ws2812_set_color_all(0, 0, 0);
+    ws2812_flush();
 #endif
 #endif
 }
 }
 
 
 void keyboard_pre_init_kb(void) {
 void keyboard_pre_init_kb(void) {
 #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
 #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
     ws2812_init();
     ws2812_init();
-    ws2812_setleds(led, RGBLIGHT_LED_COUNT);
+    ws2812_flush();
 #else
 #else
     /* Set status LEDs pins to output and Low (on) */
     /* Set status LEDs pins to output and Low (on) */
     gpio_set_pin_output(MODELM_LED_CAPSLOCK);
     gpio_set_pin_output(MODELM_LED_CAPSLOCK);
@@ -121,35 +102,59 @@ void keyboard_pre_init_kb(void) {
 #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
 #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
 static void led_update_rgb(void) {
 static void led_update_rgb(void) {
     if (isRecording && blink_state) {
     if (isRecording && blink_state) {
-        led[0] = white;
+        ws2812_set_color(0, BRIGHT, BRIGHT, BRIGHT);
     } else {
     } else {
         switch (default_layer) {
         switch (default_layer) {
             case 0:
             case 0:
-                led[0] = led_state.num_lock ? blue : lblue;
+                if (led_state.num_lock) {
+                    ws2812_set_color(0, 0, 0, BRIGHT);
+                } else {
+                    ws2812_set_color(0, 0, 0, DIM);
+                }
                 break;
                 break;
             case 1:
             case 1:
-                led[0] = led_state.num_lock ? green : black;
+                if (led_state.num_lock) {
+                    ws2812_set_color(0, 0, BRIGHT, 0);
+                } else {
+                    ws2812_set_color(0, 0, 0, 0);
+                }
                 break;
                 break;
         }
         }
     }
     }
 
 
-    led[1] = led_state.caps_lock ? green : black;
+    if (led_state.caps_lock) {
+        ws2812_set_color(1, 0, BRIGHT, 0);
+    } else {
+        ws2812_set_color(1, 0, 0, 0);
+    }
 
 
     switch (layer) {
     switch (layer) {
         case 0:
         case 0:
         case 1:
         case 1:
         default:
         default:
-            led[2] = led_state.scroll_lock ? green : black;
+            if (led_state.scroll_lock) {
+                ws2812_set_color(2, 0, BRIGHT, 0);
+            } else {
+                ws2812_set_color(2, 0, 0, 0);
+            }
             break;
             break;
         case 2:
         case 2:
-            led[2] = led_state.scroll_lock ? red : lred;
+            if (led_state.scroll_lock) {
+                ws2812_set_color(2, BRIGHT, 0, 0);
+            } else {
+                ws2812_set_color(2, DIM, 0, 0);
+            }
             break;
             break;
         case 3:
         case 3:
-            led[2] = led_state.scroll_lock ? turq : lturq;
+            if (led_state.scroll_lock) {
+                ws2812_set_color(2, 0, BRIGHT, BRIGHT);
+            } else {
+                ws2812_set_color(2, 0, DIM, DIM);
+            }
             break;
             break;
     }
     }
     if (!suspend_active) {
     if (!suspend_active) {
-	ws2812_setleds(led, RGBLIGHT_LED_COUNT);
+        ws2812_flush();
     }
     }
 }
 }
 
 

+ 4 - 0
keyboards/input_club/ergodox_infinity/ergodox_infinity.c

@@ -209,6 +209,10 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
 //                                                                       71           70           69
 //                                                                       71           70           69
                                                                     { 0, C3_7 }, { 0, C2_7 }, { 0, C1_7 },
                                                                     { 0, C3_7 }, { 0, C2_7 }, { 0, C1_7 },
 };
 };
+
+int led_matrix_led_index(int index) {
+    return index;
+}
 #endif
 #endif
 
 
 #ifdef ST7565_ENABLE
 #ifdef ST7565_ENABLE

+ 4 - 0
keyboards/keychron/q11/ansi_encoder/ansi_encoder.c

@@ -125,4 +125,8 @@ const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT] = {
     {0, CB7_CA1,  CB9_CA1,  CB8_CA1},  // Down
     {0, CB7_CA1,  CB9_CA1,  CB8_CA1},  // Down
     {0, CB7_CA7,  CB9_CA7,  CB8_CA7},  // Right
     {0, CB7_CA7,  CB9_CA7,  CB8_CA7},  // Right
 };
 };
+
+int rgb_matrix_led_index(int index) {
+    return index;
+}
 #endif
 #endif

+ 4 - 0
keyboards/keychron/q11/iso_encoder/iso_encoder.c

@@ -126,4 +126,8 @@ const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT] = {
     {0, CB7_CA1,  CB9_CA1,  CB8_CA1},  // Down
     {0, CB7_CA1,  CB9_CA1,  CB8_CA1},  // Down
     {0, CB7_CA7,  CB9_CA7,  CB8_CA7},  // Right
     {0, CB7_CA7,  CB9_CA7,  CB8_CA7},  // Right
 };
 };
+
+int rgb_matrix_led_index(int index) {
+    return index;
+}
 #endif
 #endif

+ 3 - 3
keyboards/kprepublic/bm60hsrgb/rev2/config.h

@@ -25,9 +25,9 @@
 // Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
 // Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
 // don't use those LEDs in RGB Matrix in that case.
 // don't use those LEDs in RGB Matrix in that case.
 #ifdef RGBLIGHT_ENABLE
 #ifdef RGBLIGHT_ENABLE
-#    define WS2812_LED_TOTAL 0
+#    define WS2812_LED_COUNT 0
 #else
 #else
-#    define WS2812_LED_TOTAL 6
+#    define WS2812_LED_COUNT 6
 #endif
 #endif
 
 
-#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_TOTAL)
+#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_COUNT)

+ 8 - 18
keyboards/kprepublic/bm60hsrgb/rev2/rev2.c

@@ -110,7 +110,7 @@ led_config_t g_led_config = {
     {  18,  48 }, {  30,  48 }, {  45,  48 }, {  60,  48 }, {  75,  48 }, {  90,  48 }, { 105,  48 }, { 120,  48 }, { 135,  48 }, { 150,  48 }, { 165,  48 }, { 191,  48 }, { 210,  48 },
     {  18,  48 }, {  30,  48 }, {  45,  48 }, {  60,  48 }, {  75,  48 }, {  90,  48 }, { 105,  48 }, { 120,  48 }, { 135,  48 }, { 150,  48 }, { 165,  48 }, { 191,  48 }, { 210,  48 },
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     {   3,  64 }, {  22,  64 }, {  33,  64 }, { 101,  64 }, { 135,  64 }, { 153,  64 }, { 195,  64 }, { 210,  64 }, { 225,  64 }
     {   3,  64 }, {  22,  64 }, {  33,  64 }, { 101,  64 }, { 135,  64 }, { 153,  64 }, { 195,  64 }, { 210,  64 }, { 225,  64 }
-#    if WS2812_LED_TOTAL > 0
+#    if WS2812_LED_COUNT > 0
         ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40}
         ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40}
 #    endif
 #    endif
 }, {
 }, {
@@ -124,7 +124,7 @@ led_config_t g_led_config = {
     1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4,
     1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4,
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     1, 1, 1, 4, 1, 1, 1, 1, 1
     1, 1, 1, 4, 1, 1, 1, 1, 1
-#    if WS2812_LED_TOTAL > 0
+#    if WS2812_LED_COUNT > 0
         ,2, 2, 2, 2, 2, 2
         ,2, 2, 2, 2, 2, 2
 #    endif
 #    endif
     }
     }
@@ -147,10 +147,6 @@ bool rgb_matrix_indicators_kb(void) {
 // Custom RGB Matrix driver that combines IS31FL3733 and WS2812
 // Custom RGB Matrix driver that combines IS31FL3733 and WS2812
 // ==========================================================================
 // ==========================================================================
 
 
-#    if WS2812_LED_TOTAL > 0
-rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL];
-#    endif
-
 static void rgb_matrix_driver_init(void) {
 static void rgb_matrix_driver_init(void) {
     i2c_init();
     i2c_init();
     is31fl3733_init(0);
     is31fl3733_init(0);
@@ -164,31 +160,25 @@ static void rgb_matrix_driver_init(void) {
 
 
 static void rgb_matrix_driver_flush(void) {
 static void rgb_matrix_driver_flush(void) {
     is31fl3733_update_pwm_buffers(0);
     is31fl3733_update_pwm_buffers(0);
-#    if WS2812_LED_TOTAL > 0
-    ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL);
+#    if WS2812_LED_COUNT > 0
+    ws2812_flush();
 #    endif
 #    endif
 }
 }
 
 
 static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
 static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
     if (index < IS31FL3733_LED_COUNT) {
     if (index < IS31FL3733_LED_COUNT) {
         is31fl3733_set_color(index, red, green, blue);
         is31fl3733_set_color(index, red, green, blue);
+#    if WS2812_LED_COUNT > 0
     } else {
     } else {
-#    if WS2812_LED_TOTAL > 0
-        rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].r = red;
-        rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].g = green;
-        rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].b = blue;
+        ws2812_set_color(index - IS31FL3733_LED_COUNT, red, green, blue);
 #    endif
 #    endif
     }
     }
 }
 }
 
 
 static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
 static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
     is31fl3733_set_color_all(red, green, blue);
     is31fl3733_set_color_all(red, green, blue);
-#    if WS2812_LED_TOTAL > 0
-    for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) {
-        rgb_matrix_ws2812_array[i].r = red;
-        rgb_matrix_ws2812_array[i].g = green;
-        rgb_matrix_ws2812_array[i].b = blue;
-    }
+#    if WS2812_LED_COUNT > 0
+        ws2812_set_color_all(red, green, blue);
 #    endif
 #    endif
 }
 }
 
 

+ 3 - 3
keyboards/kprepublic/bm60hsrgb_iso/rev2/config.h

@@ -23,9 +23,9 @@
 // Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
 // Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
 // don't use those LEDs in RGB Matrix in that case.
 // don't use those LEDs in RGB Matrix in that case.
 #ifdef RGBLIGHT_ENABLE
 #ifdef RGBLIGHT_ENABLE
-#    define WS2812_LED_TOTAL 0
+#    define WS2812_LED_COUNT 0
 #else
 #else
-#    define WS2812_LED_TOTAL 6
+#    define WS2812_LED_COUNT 6
 #endif
 #endif
 
 
-#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_TOTAL)
+#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_COUNT)

+ 8 - 18
keyboards/kprepublic/bm60hsrgb_iso/rev2/rev2.c

@@ -112,7 +112,7 @@ led_config_t g_led_config = { {
     {   3,  48 }, {  22,  48 }, {  33,  48 }, {  48,  48 }, {  63,  48 }, {  78,  48 }, {  93,  48 }, { 108,  48 }, { 123,  48 }, { 138,  48 }, { 153,  48 }, { 168,  48 }, { 194,  48 }, { 213,  48 },
     {   3,  48 }, {  22,  48 }, {  33,  48 }, {  48,  48 }, {  63,  48 }, {  78,  48 }, {  93,  48 }, { 108,  48 }, { 123,  48 }, { 138,  48 }, { 153,  48 }, { 168,  48 }, { 194,  48 }, { 213,  48 },
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     {   3,  64 }, {  22,  64 }, {  33,  64 }, { 101,  64 }, { 135,  64 }, { 153,  64 }, { 195,  64 }, { 210,  64 }, { 225,  64 }
     {   3,  64 }, {  22,  64 }, {  33,  64 }, { 101,  64 }, { 135,  64 }, { 153,  64 }, { 195,  64 }, { 210,  64 }, { 225,  64 }
-#    if WS2812_LED_TOTAL > 0
+#    if WS2812_LED_COUNT > 0
         ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40}
         ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40}
 #    endif
 #    endif
 }, {
 }, {
@@ -126,7 +126,7 @@ led_config_t g_led_config = { {
     1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4,
     1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4,
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     1, 1, 1, 4, 1, 1, 1, 1, 1
     1, 1, 1, 4, 1, 1, 1, 1, 1
-#    if WS2812_LED_TOTAL > 0
+#    if WS2812_LED_COUNT > 0
         ,2, 2, 2, 2, 2, 2
         ,2, 2, 2, 2, 2, 2
 #    endif
 #    endif
 } };
 } };
@@ -147,10 +147,6 @@ bool rgb_matrix_indicators_kb(void) {
 // Custom RGB Matrix driver that combines IS31FL3733 and WS2812
 // Custom RGB Matrix driver that combines IS31FL3733 and WS2812
 // ==========================================================================
 // ==========================================================================
 
 
-#    if WS2812_LED_TOTAL > 0
-rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL];
-#    endif
-
 static void rgb_matrix_driver_init(void) {
 static void rgb_matrix_driver_init(void) {
     i2c_init();
     i2c_init();
     is31fl3733_init(0);
     is31fl3733_init(0);
@@ -164,31 +160,25 @@ static void rgb_matrix_driver_init(void) {
 
 
 static void rgb_matrix_driver_flush(void) {
 static void rgb_matrix_driver_flush(void) {
     is31fl3733_update_pwm_buffers(0);
     is31fl3733_update_pwm_buffers(0);
-#    if WS2812_LED_TOTAL > 0
-    ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL);
+#    if WS2812_LED_COUNT > 0
+    ws2812_flush();
 #    endif
 #    endif
 }
 }
 
 
 static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
 static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
     if (index < IS31FL3733_LED_COUNT) {
     if (index < IS31FL3733_LED_COUNT) {
         is31fl3733_set_color(index, red, green, blue);
         is31fl3733_set_color(index, red, green, blue);
+#    if WS2812_LED_COUNT > 0
     } else {
     } else {
-#    if WS2812_LED_TOTAL > 0
-        rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].r = red;
-        rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].g = green;
-        rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].b = blue;
+        ws2812_set_color(index - IS31FL3733_LED_COUNT, red, green, blue);
 #    endif
 #    endif
     }
     }
 }
 }
 
 
 static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
 static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
     is31fl3733_set_color_all(red, green, blue);
     is31fl3733_set_color_all(red, green, blue);
-#    if WS2812_LED_TOTAL > 0
-    for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) {
-        rgb_matrix_ws2812_array[i].r = red;
-        rgb_matrix_ws2812_array[i].g = green;
-        rgb_matrix_ws2812_array[i].b = blue;
-    }
+#    if WS2812_LED_COUNT > 0
+    ws2812_set_color_all(red, green, blue);
 #    endif
 #    endif
 }
 }
 
 

+ 3 - 3
keyboards/kprepublic/bm60hsrgb_poker/rev2/config.h

@@ -21,9 +21,9 @@
 // Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
 // Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
 // don't use those LEDs in RGB Matrix in that case.
 // don't use those LEDs in RGB Matrix in that case.
 #ifdef RGBLIGHT_ENABLE
 #ifdef RGBLIGHT_ENABLE
-#    define WS2812_LED_TOTAL 0
+#    define WS2812_LED_COUNT 0
 #else
 #else
-#    define WS2812_LED_TOTAL 6
+#    define WS2812_LED_COUNT 6
 #endif
 #endif
 
 
-#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_TOTAL)
+#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_COUNT)

+ 8 - 18
keyboards/kprepublic/bm60hsrgb_poker/rev2/rev2.c

@@ -107,7 +107,7 @@ led_config_t g_led_config = {
     {  18,  48 }, {  30,  48 }, {  45,  48 }, {  60,  48 }, {  75,  48 }, {  90,  48 }, { 105,  48 }, { 120,  48 }, { 135,  48 }, { 150,  48 }, { 165,  48 }, { 191,  48 },
     {  18,  48 }, {  30,  48 }, {  45,  48 }, {  60,  48 }, {  75,  48 }, {  90,  48 }, { 105,  48 }, { 120,  48 }, { 135,  48 }, { 150,  48 }, { 165,  48 }, { 191,  48 },
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     {   3,  64 }, {  22,  64 }, {  33,  64 }, { 101,  64 }, { 135,  64 }, { 153,  64 }, { 210,  64 }, { 225,  64 }
     {   3,  64 }, {  22,  64 }, {  33,  64 }, { 101,  64 }, { 135,  64 }, { 153,  64 }, { 210,  64 }, { 225,  64 }
-#    if WS2812_LED_TOTAL > 0
+#    if WS2812_LED_COUNT > 0
         ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40}
         ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40}
 #    endif
 #    endif
 }, {
 }, {
@@ -121,7 +121,7 @@ led_config_t g_led_config = {
     1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
     1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
     1, 1, 1, 4, 1, 1, 1, 1
     1, 1, 1, 4, 1, 1, 1, 1
-#    if WS2812_LED_TOTAL > 0
+#    if WS2812_LED_COUNT > 0
         ,2, 2, 2, 2, 2, 2
         ,2, 2, 2, 2, 2, 2
 #    endif
 #    endif
     }
     }
@@ -143,10 +143,6 @@ bool rgb_matrix_indicators_kb(void) {
 // Custom RGB Matrix driver that combines IS31FL3733 and WS2812
 // Custom RGB Matrix driver that combines IS31FL3733 and WS2812
 // ==========================================================================
 // ==========================================================================
 
 
-#    if WS2812_LED_TOTAL > 0
-rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL];
-#    endif
-
 static void rgb_matrix_driver_init(void) {
 static void rgb_matrix_driver_init(void) {
     i2c_init();
     i2c_init();
     is31fl3733_init(0);
     is31fl3733_init(0);
@@ -160,31 +156,25 @@ static void rgb_matrix_driver_init(void) {
 
 
 static void rgb_matrix_driver_flush(void) {
 static void rgb_matrix_driver_flush(void) {
     is31fl3733_update_pwm_buffers(0);
     is31fl3733_update_pwm_buffers(0);
-#    if WS2812_LED_TOTAL > 0
-    ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL);
+#    if WS2812_LED_COUNT > 0
+    ws2812_flush();
 #    endif
 #    endif
 }
 }
 
 
 static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
 static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
     if (index < IS31FL3733_LED_COUNT) {
     if (index < IS31FL3733_LED_COUNT) {
         is31fl3733_set_color(index, red, green, blue);
         is31fl3733_set_color(index, red, green, blue);
+#    if WS2812_LED_COUNT > 0
     } else {
     } else {
-#    if WS2812_LED_TOTAL > 0
-        rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].r = red;
-        rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].g = green;
-        rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].b = blue;
+        ws2812_set_color(index - IS31FL3733_LED_COUNT, red, green, blue);
 #    endif
 #    endif
     }
     }
 }
 }
 
 
 static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
 static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
     is31fl3733_set_color_all(red, green, blue);
     is31fl3733_set_color_all(red, green, blue);
-#    if WS2812_LED_TOTAL > 0
-    for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) {
-        rgb_matrix_ws2812_array[i].r = red;
-        rgb_matrix_ws2812_array[i].g = green;
-        rgb_matrix_ws2812_array[i].b = blue;
-    }
+#    if WS2812_LED_COUNT > 0
+    ws2812_set_color_all(red, green, blue);
 #    endif
 #    endif
 }
 }
 
 

+ 23 - 22
keyboards/matrix/abelx/abelx.c

@@ -41,20 +41,6 @@ uint8_t read_pin(uint16_t pin)
     return (data & (1<<GET_PIN(pin))) ? 1 : 0;
     return (data & (1<<GET_PIN(pin))) ? 1 : 0;
 }
 }
 
 
-void matrix_init_kb(void) {
-#ifdef RGBLIGHT_ENABLE
-    aw9523b_init(AW9523B_ADDR);
-#endif
-    matrix_init_user();
-}
-
-
-void housekeeping_task_kb(void) {
-#ifdef RGBLIGHT_ENABLE
-    aw9523b_update_pwm_buffers(AW9523B_ADDR);
-#endif
-}
-
 #ifdef RGBLIGHT_ENABLE
 #ifdef RGBLIGHT_ENABLE
 #include "rgblight.h"
 #include "rgblight.h"
 #include "ws2812.h"
 #include "ws2812.h"
@@ -67,20 +53,35 @@ const aw9523b_led g_aw9523b_leds[AW9523B_RGB_NUM] = {
     {AW9523B_P07_PWM, AW9523B_P06_PWM, AW9523B_P05_PWM},
     {AW9523B_P07_PWM, AW9523B_P06_PWM, AW9523B_P05_PWM},
 };
 };
 
 
-void setleds_custom(rgb_led_t *start_led, uint16_t num_leds)
-{
-    uint8_t num = num_leds < AW9523B_RGB_NUM ? num_leds : AW9523B_RGB_NUM;
+void init_custom(void) {
+    aw9523b_init(AW9523B_ADDR);
+    ws2812_init();
+}
 
 
-    ws2812_setleds(start_led, num);
+void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    if (index < AW9523B_RGB_NUM) {
+        aw9523b_set_color(index, red, green, blue);
+    } else {
+        ws2812_set_color(index - AW9523B_RGB_NUM, red, green, blue);
+    }
+}
 
 
-    for (int i = 0; i < num; i++) {
-        aw9523b_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b);
+void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) {
+        set_color_custom(i, red, green, blue);
     }
     }
 }
 }
 
 
+void flush_custom(void) {
+    aw9523b_update_pwm_buffers(AW9523B_ADDR);
+    ws2812_flush();
+}
+
 const rgblight_driver_t rgblight_driver = {
 const rgblight_driver_t rgblight_driver = {
-    .init    = ws2812_init,
-    .setleds = setleds_custom,
+    .init          = init_custom,
+    .set_color     = set_color_custom,
+    .set_color_all = set_color_all_custom,
+    .flush         = flush_custom,
 };
 };
 
 
 #endif
 #endif

+ 1 - 0
keyboards/matrix/abelx/config.h

@@ -89,5 +89,6 @@
 #define I2C1_DUTY_CYCLE FAST_DUTY_CYCLE_2
 #define I2C1_DUTY_CYCLE FAST_DUTY_CYCLE_2
 
 
 #define AW9523B_RGB_NUM 4
 #define AW9523B_RGB_NUM 4
+#define WS2812_LED_COUNT 5
 
 
 #define EARLY_INIT_PERFORM_BOOTLOADER_JUMP FALSE
 #define EARLY_INIT_PERFORM_BOOTLOADER_JUMP FALSE

+ 0 - 7
keyboards/matrix/m20add/m20add.c

@@ -27,13 +27,6 @@ uint8_t read_pin(uint16_t pin)
     return (data & (1<<GET_PIN(pin))) ? 1 : 0;
     return (data & (1<<GET_PIN(pin))) ? 1 : 0;
 }
 }
 
 
-void matrix_init_kb(void) {
-#ifdef RGBLIGHT_ENABLE
-    rgb_ring_init();
-#endif
-    matrix_init_user();
-}
-
 void housekeeping_task_kb(void) {
 void housekeeping_task_kb(void) {
 #ifdef RGBLIGHT_ENABLE
 #ifdef RGBLIGHT_ENABLE
     rgb_ring_task();
     rgb_ring_task();

+ 6 - 13
keyboards/matrix/m20add/rgb_ring.c

@@ -361,27 +361,22 @@ static void custom_effects(void)
     effect_funcs[rgb_ring.effect]();
     effect_funcs[rgb_ring.effect]();
 }
 }
 
 
-void setleds_custom(rgb_led_t *start_led, uint16_t num_leds)
-{
+void flush_custom(void) {
     if (rgb_ring.state != RING_STATE_QMK) {
     if (rgb_ring.state != RING_STATE_QMK) {
         return;
         return;
     }
     }
 
 
-    for (uint8_t i = 0; i < num_leds; i++) {
-        is31fl3731_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b);
-    }
+    is31fl3731_flush();
 }
 }
 
 
 const rgblight_driver_t rgblight_driver = {
 const rgblight_driver_t rgblight_driver = {
-    .setleds = setleds_custom,
+    .init          = is31fl3731_init_drivers,
+    .set_color     = is31fl3731_set_color,
+    .set_color_all = is31fl3731_set_color_all,
+    .flush         = flush_custom,
 };
 };
 
 
 
 
-void rgb_ring_init(void)
-{
-    is31fl3731_init_drivers();
-}
-
 void rgb_ring_task(void)
 void rgb_ring_task(void)
 {
 {
     switch (rgb_ring.state) {
     switch (rgb_ring.state) {
@@ -397,8 +392,6 @@ void rgb_ring_task(void)
         default:
         default:
             break;
             break;
     };
     };
-
-    is31fl3731_flush();
 }
 }
 
 
 bool process_record_kb(uint16_t keycode, keyrecord_t *record)
 bool process_record_kb(uint16_t keycode, keyrecord_t *record)

+ 0 - 1
keyboards/matrix/m20add/rgb_ring.h

@@ -19,5 +19,4 @@
 
 
 #pragma once
 #pragma once
 
 
-void rgb_ring_init(void);
 void rgb_ring_task(void);
 void rgb_ring_task(void);

+ 1 - 1
keyboards/matrix/noah/keyboard.json

@@ -10,7 +10,7 @@
     "no_startup_check": true
     "no_startup_check": true
   },
   },
   "rgblight": {
   "rgblight": {
-    "driver": "custom",
+    "driver": "ws2812",
     "led_count": 7,
     "led_count": 7,
     "animations": {
     "animations": {
       "breathing": true,
       "breathing": true,

+ 0 - 57
keyboards/matrix/noah/noah.c

@@ -9,57 +9,6 @@ void bootloader_jump(void) {
     NVIC_SystemReset();
     NVIC_SystemReset();
 }
 }
 
 
-#ifdef RGBLIGHT_ENABLE
-#include <string.h>
-#include "rgblight.h"
-#include "ws2812.h"
-extern rgblight_config_t rgblight_config;
-
-// led 0 for caps lock, led 1 for scroll lock, led 3 for num lock
-// led 4 for layer 1, led 5 for layer 2, led 6 for layer 3, led 7 for layer 4
-#if RGBLIGHT_LED_COUNT < 7
-#error "MUST set the RGBLIGHT_LED_COUNT bigger than 7"
-#endif
-rgb_led_t noah_leds[RGBLIGHT_LED_COUNT];
-static bool noah_led_mode = false;
-void setleds_custom(rgb_led_t *ledarray, uint16_t num_leds) {
-    memset(&noah_leds[0], 0, sizeof(noah_leds));
-    if (!rgblight_config.enable) {
-        for (uint8_t i = 0; i < RGBLIGHT_LED_COUNT; i++) {
-            ledarray[i].r = 0;
-            ledarray[i].g = 0;
-            ledarray[i].b = 0;
-        }
-    }
-    if (noah_led_mode) {
-      led_t led_state = host_keyboard_led_state();
-      if (led_state.caps_lock) {
-        noah_leds[0] = ledarray[0];
-      }
-      if (led_state.scroll_lock) {
-        noah_leds[1] = ledarray[1];
-      }
-      if (led_state.num_lock) {
-        noah_leds[2] = ledarray[2];
-      }
-      for (int32_t i = 0; i < 4; i++) {
-        if(layer_state_is(i+1)) {
-          noah_leds[i + 3] = ledarray[i + 3];
-        }
-      }
-    } else {
-      memcpy(&noah_leds[0], &ledarray[0], sizeof(noah_leds));
-    }
-
-  ws2812_setleds(noah_leds, RGBLIGHT_LED_COUNT);
-}
-
-const rgblight_driver_t rgblight_driver = {
-    .init    = ws2812_init,
-    .setleds = setleds_custom,
-};
-#endif
-
 #ifdef RGB_MATRIX_ENABLE
 #ifdef RGB_MATRIX_ENABLE
 const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
 const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
 /* Refer to IS31 manual for these locations
 /* Refer to IS31 manual for these locations
@@ -150,11 +99,6 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
   if (record->event.pressed) {
   if (record->event.pressed) {
     switch(keycode) {
     switch(keycode) {
-    #ifdef RGBLIGHT_ENABLE
-        case KC_F24: // switch the led mode on or off
-        noah_led_mode = !noah_led_mode;
-        return false;
-
     #ifdef RGB_MATRIX_ENABLE
     #ifdef RGB_MATRIX_ENABLE
         case KC_F13: // toggle rgb matrix
         case KC_F13: // toggle rgb matrix
         rgb_matrix_toggle();
         rgb_matrix_toggle();
@@ -162,7 +106,6 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
         case KC_F14:
         case KC_F14:
         rgb_matrix_step();
         rgb_matrix_step();
         return false;
         return false;
-    #endif
     #endif
     #endif
         default:
         default:
         break;
         break;

+ 33 - 28
keyboards/neson_design/700e/700e.c

@@ -18,9 +18,11 @@
  */
  */
 
 
 #include "quantum.h"
 #include "quantum.h"
-#include "i2c_master.h"
-#include "drivers/led/issi/is31fl3731.h"
-#include "ws2812.h"
+
+#ifdef RGBLIGHT_ENABLE
+#    include "i2c_master.h"
+#    include "drivers/led/issi/is31fl3731.h"
+#    include "ws2812.h"
 
 
 enum {
 enum {
     SELF_TESTING,
     SELF_TESTING,
@@ -67,7 +69,6 @@ enum {
 #endif
 #endif
 #define ST_RIGHT_END        (ST_RIGHT_BEGIN+ST_RIGHT_SIZE-1)
 #define ST_RIGHT_END        (ST_RIGHT_BEGIN+ST_RIGHT_SIZE-1)
 
 
-#ifdef RGBLIGHT_ENABLE
 
 
 typedef struct {
 typedef struct {
     uint8_t state;
     uint8_t state;
@@ -295,7 +296,6 @@ void matrix_init_kb(void)
     gpio_set_pin_output(LED_CAPS_LOCK_PIN);
     gpio_set_pin_output(LED_CAPS_LOCK_PIN);
     gpio_write_pin_low(LED_CAPS_LOCK_PIN);
     gpio_write_pin_low(LED_CAPS_LOCK_PIN);
 
 
-    is31fl3731_init_drivers();
 
 
     update_ticks();
     update_ticks();
     matrix_init_user();
     matrix_init_user();
@@ -313,17 +313,10 @@ void housekeeping_task_kb(void)
     } else if (rgb_state.state == CAPS_ALERT) {
     } else if (rgb_state.state == CAPS_ALERT) {
         if (rgb_state.alert) {
         if (rgb_state.alert) {
             is31fl3731_set_color_all(ALERM_LED_R, ALERM_LED_G, ALERM_LED_B);
             is31fl3731_set_color_all(ALERM_LED_R, ALERM_LED_G, ALERM_LED_B);
-            rgb_led_t leds[4];
-            for (int i = 0; i < 4; i++) {
-                leds[i].r = ALERM_LED_G;
-                leds[i].g = ALERM_LED_R;
-                leds[i].b = ALERM_LED_B;
-            }
-            ws2812_setleds(leds, 4);
+            ws2812_set_color_all(ALERM_LED_G, ALERM_LED_R, ALERM_LED_B);
         } else {
         } else {
             is31fl3731_set_color_all(0, 0, 0);
             is31fl3731_set_color_all(0, 0, 0);
-            rgb_led_t leds[4] = {0};
-            ws2812_setleds(leds, 4);
+            ws2812_set_color_all(0, 0, 0);
         }
         }
 
 
         if (timer_elapsed(rgb_state.ticks) > ALERT_INTERVAL) {
         if (timer_elapsed(rgb_state.ticks) > ALERT_INTERVAL) {
@@ -333,28 +326,40 @@ void housekeeping_task_kb(void)
     }
     }
 
 
     is31fl3731_flush();
     is31fl3731_flush();
+    ws2812_flush();
 }
 }
 
 
-void setleds_custom(rgb_led_t *start_led, uint16_t num_leds)
-{
-    if (rgb_state.state != NORMAL) return;
+void init_custom(void) {
+    is31fl3731_init_drivers();
+    ws2812_init();
+}
 
 
-    for (uint8_t i = 0; i < IS31FL3731_LED_COUNT; i++) {
-        is31fl3731_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b);
+void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    if (index < IS31FL3731_LED_COUNT) {
+        is31fl3731_set_color(index, red, green, blue);
+    } else if (index < IS31FL3731_LED_COUNT + WS2812_LED_COUNT) {
+        ws2812_set_color(index - IS31FL3731_LED_COUNT, green, red, blue);
     }
     }
-    rgb_led_t leds[4];
-    for (int i = 0; i < 4; i++) {
-        leds[i].r = start_led[IS31FL3731_LED_COUNT+i].g;
-        leds[i].g = start_led[IS31FL3731_LED_COUNT+i].r;
-        leds[i].b = start_led[IS31FL3731_LED_COUNT+i].b;
+}
+
+void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) {
+        set_color_custom(i, red, green, blue);
     }
     }
-    //ws2812_setleds(start_led+IS31FL3731_LED_COUNT, 4);
-    ws2812_setleds(leds, 4);
+}
+
+void flush_custom(void) {
+    if (rgb_state.state != NORMAL) return;
+
+    is31fl3731_flush();
+    ws2812_flush();
 }
 }
 
 
 const rgblight_driver_t rgblight_driver = {
 const rgblight_driver_t rgblight_driver = {
-    .init    = ws2812_init,
-    .setleds = setleds_custom,
+    .init          = init_custom,
+    .set_color     = set_color_custom,
+    .set_color_all = set_color_all_custom,
+    .flush         = flush_custom,
 };
 };
 
 
 bool led_update_kb(led_t led_state)
 bool led_update_kb(led_t led_state)

+ 1 - 0
keyboards/neson_design/700e/config.h

@@ -21,5 +21,6 @@
 #define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND
 #define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND
 #define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_VCC
 #define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_VCC
 #define IS31FL3731_LED_COUNT 64
 #define IS31FL3731_LED_COUNT 64
+#define WS2812_LED_COUNT 4
 
 
 #define USB_SUSPEND_WAKEUP_DELAY 1000
 #define USB_SUSPEND_WAKEUP_DELAY 1000

+ 1 - 0
keyboards/neson_design/n6/config.h

@@ -21,3 +21,4 @@
 #define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND
 #define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND
 #define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_VCC
 #define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_VCC
 #define IS31FL3731_LED_COUNT 64
 #define IS31FL3731_LED_COUNT 64
+#define WS2812_LED_COUNT 1

+ 34 - 27
keyboards/neson_design/n6/n6.c

@@ -18,9 +18,11 @@
  */
  */
 
 
 #include "quantum.h"
 #include "quantum.h"
-#include "i2c_master.h"
-#include "drivers/led/issi/is31fl3731.h"
-#include "ws2812.h"
+
+#ifdef RGBLIGHT_ENABLE
+#    include "i2c_master.h"
+#    include "drivers/led/issi/is31fl3731.h"
+#    include "ws2812.h"
 
 
 enum {
 enum {
     SELF_TESTING,
     SELF_TESTING,
@@ -67,7 +69,6 @@ enum {
 #endif
 #endif
 #define ST_RIGHT_END        (ST_RIGHT_BEGIN+ST_RIGHT_SIZE-1)
 #define ST_RIGHT_END        (ST_RIGHT_BEGIN+ST_RIGHT_SIZE-1)
 
 
-#ifdef RGBLIGHT_ENABLE
 extern rgblight_config_t rgblight_config;
 extern rgblight_config_t rgblight_config;
 
 
 typedef struct {
 typedef struct {
@@ -299,8 +300,6 @@ void matrix_init_kb(void)
     gpio_set_pin_output(LED_CAPS_LOCK_PIN);
     gpio_set_pin_output(LED_CAPS_LOCK_PIN);
     gpio_write_pin_low(LED_CAPS_LOCK_PIN);
     gpio_write_pin_low(LED_CAPS_LOCK_PIN);
 
 
-    is31fl3731_init_drivers();
-
     update_ticks();
     update_ticks();
     matrix_init_user();
     matrix_init_user();
 }
 }
@@ -310,22 +309,12 @@ void housekeeping_task_kb(void)
     if (rgb_state.state == SELF_TESTING) {
     if (rgb_state.state == SELF_TESTING) {
         self_testing();
         self_testing();
     } else if (rgb_state.state == CAPS_ALERT) {
     } else if (rgb_state.state == CAPS_ALERT) {
-        //gold 0xFF, 0xD9, 0x00
-        rgb_led_t led = {
-            .r = 0xFF,
-            //.g = 0xD9,
-            .g = 0xA5,
-            .b = 0x00,
-        };
         if (rgb_state.alert) {
         if (rgb_state.alert) {
-            is31fl3731_set_color_all(led.r, led.g, led.b);
-            ws2812_setleds(&led, 1);
+            is31fl3731_set_color_all(0xFF, 0xA5, 0x00);
+            ws2812_set_color_all(0xFF, 0xA5, 0x00);
         } else {
         } else {
-            led.r = 0;
-            led.g = 0;
-            led.b = 0;
             is31fl3731_set_color_all(0, 0, 0);
             is31fl3731_set_color_all(0, 0, 0);
-            ws2812_setleds(&led, 1);
+            ws2812_set_color_all(0, 0, 0);
         }
         }
 
 
         if (timer_elapsed(rgb_state.ticks) > ALERT_INTERVAL) {
         if (timer_elapsed(rgb_state.ticks) > ALERT_INTERVAL) {
@@ -337,19 +326,37 @@ void housekeeping_task_kb(void)
     is31fl3731_flush();
     is31fl3731_flush();
 }
 }
 
 
-void setleds_custom(rgb_led_t *start_led, uint16_t num_leds)
-{
-    if (rgb_state.state != NORMAL) return;
+void init_custom(void) {
+    is31fl3731_init_drivers();
+    ws2812_init();
+}
 
 
-    for (uint8_t i = 0; i < IS31FL3731_LED_COUNT; i++) {
-        is31fl3731_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b);
+void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    if (index < IS31FL3731_LED_COUNT) {
+        is31fl3731_set_color(index, red, green, blue);
+    } else if (index < IS31FL3731_LED_COUNT + WS2812_LED_COUNT) {
+        ws2812_set_color(index - IS31FL3731_LED_COUNT, red, green, blue);
     }
     }
-    ws2812_setleds(start_led+IS31FL3731_LED_COUNT, 1);
+}
+
+void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) {
+        set_color_custom(i, red, green, blue);
+    }
+}
+
+void flush_custom(void) {
+    if (rgb_state.state != NORMAL) return;
+
+    is31fl3731_flush();
+    ws2812_flush();
 }
 }
 
 
 const rgblight_driver_t rgblight_driver = {
 const rgblight_driver_t rgblight_driver = {
-    .init    = ws2812_init,
-    .setleds = setleds_custom,
+    .init          = init_custom,
+    .set_color     = set_color_custom,
+    .set_color_all = set_color_all_custom,
+    .flush         = flush_custom,
 };
 };
 
 
 bool led_update_kb(led_t led_state)
 bool led_update_kb(led_t led_state)

+ 17 - 4
keyboards/oddforge/vea/ws2812_custom.c

@@ -17,12 +17,25 @@
 #    define WS2812_I2C_TIMEOUT 100
 #    define WS2812_I2C_TIMEOUT 100
 #endif
 #endif
 
 
+ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
+
 void ws2812_init(void) {
 void ws2812_init(void) {
     i2c_init();
     i2c_init();
 }
 }
 
 
-// Setleds for standard RGB
-void ws2812_setleds(rgb_led_t *ledarray, uint16_t leds) {
-    i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ledarray, sizeof(rgb_led_t) * (leds >> 1), WS2812_I2C_TIMEOUT);
-    i2c_transmit(WS2812_I2C_ADDRESS_RIGHT, (uint8_t *)ledarray+(sizeof(rgb_led_t) * (leds >> 1)), sizeof(rgb_led_t) * (leds - (leds >> 1)), WS2812_I2C_TIMEOUT);
+void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    ws2812_leds[index].r = red;
+    ws2812_leds[index].g = green;
+    ws2812_leds[index].b = blue;
+}
+
+void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
+        ws2812_set_color(i, red, green, blue);
+    }
+}
+
+void ws2812_flush(void) {
+    i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ws2812_leds, sizeof(ws2812_led_t) * (WS2812_LED_COUNT >> 1), WS2812_I2C_TIMEOUT);
+    i2c_transmit(WS2812_I2C_ADDRESS_RIGHT, (uint8_t *)ws2812_leds + (sizeof(ws2812_led_t) * (WS2812_LED_COUNT >> 1)), sizeof(ws2812_led_t) * (WS2812_LED_COUNT - (WS2812_LED_COUNT >> 1)), WS2812_I2C_TIMEOUT);
 }
 }

+ 3 - 0
keyboards/orthograph/orthograph.c

@@ -125,4 +125,7 @@ const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT] = {
 {0, SW7_CS7, SW8_CS7, SW9_CS7}
 {0, SW7_CS7, SW8_CS7, SW9_CS7}
 };
 };
 
 
+int rgb_matrix_led_index(int index) {
+    return index;
+}
 #endif
 #endif

+ 1 - 0
keyboards/rgbkb/pan/config.h

@@ -17,3 +17,4 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #pragma once
 #pragma once
 
 
 #define RGB_MATRIX_LED_COUNT 64
 #define RGB_MATRIX_LED_COUNT 64
+#define WS2812_LED_COUNT 64

+ 4 - 24
keyboards/rgbkb/pan/pan.c

@@ -21,43 +21,23 @@
 #    if defined(KEYBOARD_rgbkb_pan_rev1)
 #    if defined(KEYBOARD_rgbkb_pan_rev1)
 #        include "ws2812.h"
 #        include "ws2812.h"
 
 
-// LED color buffer
-rgb_led_t rgb_matrix_ws2812_array[RGB_MATRIX_LED_COUNT];
-
-static void flush(void) {
-    ws2812_setleds(rgb_matrix_ws2812_array, RGB_MATRIX_LED_COUNT);
-}
-
 // Set an led in the buffer to a color
 // Set an led in the buffer to a color
 static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) {
 static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) {
 #        if defined(RGB_ENCODERS) || defined(STAGGERED_RGB_ENCODERS)
 #        if defined(RGB_ENCODERS) || defined(STAGGERED_RGB_ENCODERS)
     if (i == 0 || i == 1) {  // if encoder LEDs, change LEDs
     if (i == 0 || i == 1) {  // if encoder LEDs, change LEDs
-        rgb_matrix_ws2812_array[i].r = g;
-        rgb_matrix_ws2812_array[i].g = b;
-        rgb_matrix_ws2812_array[i].b = r;
+        ws2812_set_color(i, g, b, r);
     } else
     } else
 #        endif
 #        endif
     {
     {
-        rgb_matrix_ws2812_array[i].r = r;
-        rgb_matrix_ws2812_array[i].g = g;
-        rgb_matrix_ws2812_array[i].b = b;
-    }
-#        ifdef WS2812_RGBW
-    convert_rgb_to_rgbw(&rgb_matrix_ws2812_array[i]);
-#        endif
-}
-
-static void setled_all(uint8_t r, uint8_t g, uint8_t b) {
-    for (int i = 0; i < ARRAY_SIZE(rgb_matrix_ws2812_array); i++) {
-        setled(i, r, g, b);
+        ws2812_set_color(i, r, g, b);
     }
     }
 }
 }
 
 
 const rgb_matrix_driver_t rgb_matrix_driver = {
 const rgb_matrix_driver_t rgb_matrix_driver = {
     .init          = ws2812_init,
     .init          = ws2812_init,
-    .flush         = flush,
+    .flush         = ws2812_flush,
     .set_color     = setled,
     .set_color     = setled,
-    .set_color_all = setled_all,
+    .set_color_all = ws2812_set_color_all,
 };
 };
 #    endif
 #    endif
 
 

+ 40 - 20
keyboards/steelseries/prime_plus/rgblight_custom.c

@@ -1,45 +1,65 @@
 // Copyright 2024 Dasky (@daskygit)
 // Copyright 2024 Dasky (@daskygit)
 // SPDX-License-Identifier: GPL-2.0-or-later
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 
-#include "quantum.h"
+#include <hal.h>
+#include "chibios_config.h"
+#include "gpio.h"
+#include "color.h"
+#include "rgblight_drivers.h"
 
 
 static PWMConfig pwmCFG = {
 static PWMConfig pwmCFG = {
     .frequency = 0xFFFF,
     .frequency = 0xFFFF,
     .period    = 256,
     .period    = 256,
 };
 };
 
 
-void prime_setleds(rgb_led_t *start_led, uint16_t num_leds) {
-    if (start_led[0].r == 0) {
+rgb_led_t prime_leds[RGBLIGHT_LED_COUNT];
+
+void init_custom(void) {
+    palSetPadMode(PAL_PORT(RGB_RED_PIN), PAL_PAD(RGB_RED_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
+    palSetPadMode(PAL_PORT(RGB_GREEN_PIN), PAL_PAD(RGB_GREEN_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
+    palSetPadMode(PAL_PORT(RGB_BLUE_PIN), PAL_PAD(RGB_BLUE_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
+    pwmCFG.channels[RGB_RED_PWM_CHANNEL - 1].mode   = PWM_OUTPUT_ACTIVE_HIGH;
+    pwmCFG.channels[RGB_GREEN_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
+    pwmCFG.channels[RGB_BLUE_PWM_CHANNEL - 1].mode  = PWM_OUTPUT_ACTIVE_HIGH;
+    pwmStart(&RGB_PWM_DRIVER, &pwmCFG);
+}
+
+void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    prime_leds[index].r = red;
+    prime_leds[index].g = green;
+    prime_leds[index].b = blue;
+}
+
+void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) {
+        set_color_custom(i, red, green, blue);
+    }
+}
+
+void flush_custom(void) {
+    if (prime_leds[0].r == 0) {
         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1);
         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1);
     } else {
     } else {
-        uint32_t duty = ((uint32_t)0xFFFF * start_led[0].r) / 0xFF;
+        uint32_t duty = ((uint32_t)0xFFFF * prime_leds[0].r) / 0xFF;
         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
     }
     }
-    if (start_led[0].g == 0) {
+    if (prime_leds[0].g == 0) {
         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1);
         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1);
     } else {
     } else {
-        uint32_t duty = ((uint32_t)0xFFFF * start_led[0].g) / 0xFF;
+        uint32_t duty = ((uint32_t)0xFFFF * prime_leds[0].g) / 0xFF;
         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
     }
     }
-    if (start_led[0].b == 0) {
+    if (prime_leds[0].b == 0) {
         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1);
         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1);
     } else {
     } else {
-        uint32_t duty = ((uint32_t)0xFFFF * start_led[0].b) / 0xFF;
+        uint32_t duty = ((uint32_t)0xFFFF * prime_leds[0].b) / 0xFF;
         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
     }
     }
 }
 }
 
 
-void prime_initleds(void) {
-    palSetPadMode(PAL_PORT(RGB_RED_PIN), PAL_PAD(RGB_RED_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
-    palSetPadMode(PAL_PORT(RGB_GREEN_PIN), PAL_PAD(RGB_GREEN_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
-    palSetPadMode(PAL_PORT(RGB_BLUE_PIN), PAL_PAD(RGB_BLUE_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
-    pwmCFG.channels[RGB_RED_PWM_CHANNEL - 1].mode   = PWM_OUTPUT_ACTIVE_HIGH;
-    pwmCFG.channels[RGB_GREEN_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
-    pwmCFG.channels[RGB_BLUE_PWM_CHANNEL - 1].mode  = PWM_OUTPUT_ACTIVE_HIGH;
-    pwmStart(&RGB_PWM_DRIVER, &pwmCFG);
-}
-
 const rgblight_driver_t rgblight_driver = {
 const rgblight_driver_t rgblight_driver = {
-    .init    = prime_initleds,
-    .setleds = prime_setleds,
+    .init          = init_custom,
+    .set_color     = set_color_custom,
+    .set_color_all = set_color_all_custom,
+    .flush         = flush_custom,
 };
 };

+ 6 - 12
keyboards/wilba_tech/wt_rgb_backlight.c

@@ -60,7 +60,6 @@
 
 
 #if defined(RGB_BACKLIGHT_DAWN60)
 #if defined(RGB_BACKLIGHT_DAWN60)
 #include "ws2812.h"
 #include "ws2812.h"
-rgb_led_t g_ws2812_leds[WS2812_LED_TOTAL];
 #endif
 #endif
 
 
 #include "progmem.h"
 #include "progmem.h"
@@ -1011,6 +1010,9 @@ void backlight_update_pwm_buffers(void)
         driver = 0;
         driver = 0;
     }
     }
 #else
 #else
+#if defined(RGB_BACKLIGHT_DAWN60)
+    ws2812_flush();
+#endif
     is31fl3731_update_pwm_buffers( 0 );
     is31fl3731_update_pwm_buffers( 0 );
     is31fl3731_update_pwm_buffers( 1 );
     is31fl3731_update_pwm_buffers( 1 );
     is31fl3731_update_led_control_registers( 0 );
     is31fl3731_update_led_control_registers( 0 );
@@ -1037,10 +1039,7 @@ void backlight_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
     if( index < IS31FL3731_LED_COUNT ) {
     if( index < IS31FL3731_LED_COUNT ) {
         is31fl3731_set_color( index, red, green, blue );
         is31fl3731_set_color( index, red, green, blue );
     } else {
     } else {
-        g_ws2812_leds[index - IS31FL3731_LED_COUNT].r = red;
-        g_ws2812_leds[index - IS31FL3731_LED_COUNT].g = green;
-        g_ws2812_leds[index - IS31FL3731_LED_COUNT].b = blue;
-        ws2812_setleds(g_ws2812_leds, WS2812_LED_TOTAL);
+        ws2812_set_color( index - IS31FL3731_LED_COUNT, red, green, blue );
     }
     }
 #else
 #else
     is31fl3731_set_color( index, red, green, blue );
     is31fl3731_set_color( index, red, green, blue );
@@ -1075,12 +1074,7 @@ void backlight_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
     }
     }
 #elif defined(RGB_BACKLIGHT_DAWN60)
 #elif defined(RGB_BACKLIGHT_DAWN60)
     is31fl3731_set_color_all( red, green, blue );
     is31fl3731_set_color_all( red, green, blue );
-    for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) {
-        g_ws2812_leds[i].r = red;
-        g_ws2812_leds[i].g = green;
-        g_ws2812_leds[i].b = blue;
-    }
-    ws2812_setleds(g_ws2812_leds, WS2812_LED_TOTAL);
+    ws2812_set_color_all( red, green, blue );
 #else
 #else
     is31fl3731_set_color_all( red, green, blue );
     is31fl3731_set_color_all( red, green, blue );
 #endif
 #endif
@@ -1325,7 +1319,7 @@ void backlight_effect_alphas_mods(void)
         }
         }
     }
     }
 #if defined(RGB_BACKLIGHT_DAWN60)
 #if defined(RGB_BACKLIGHT_DAWN60)
-    for (int i = 0; i < WS2812_LED_TOTAL; i++) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
         if ((RGB_UNDERGLOW_ALPHA_TOP_START <= i && i <= RGB_UNDERGLOW_ALPHA_TOP_END) ||
         if ((RGB_UNDERGLOW_ALPHA_TOP_START <= i && i <= RGB_UNDERGLOW_ALPHA_TOP_END) ||
             (RGB_UNDERGLOW_ALPHA_BOT_START <= i && i <= RGB_UNDERGLOW_ALPHA_BOT_END)) {
             (RGB_UNDERGLOW_ALPHA_BOT_START <= i && i <= RGB_UNDERGLOW_ALPHA_BOT_END)) {
             backlight_set_color(i + IS31FL3731_LED_COUNT, rgb1.r, rgb1.g, rgb1.b);
             backlight_set_color(i + IS31FL3731_LED_COUNT, rgb1.r, rgb1.g, rgb1.b);

+ 7 - 3
keyboards/work_louder/rgb_functions.c

@@ -26,13 +26,17 @@
 #define WS2812_DI_PIN RGBLIGHT_DI_PIN
 #define WS2812_DI_PIN RGBLIGHT_DI_PIN
 
 
 #define ws2812_init ws2812_rgb_init
 #define ws2812_init ws2812_rgb_init
-#define ws2812_setleds ws2812_rgb_setleds
+#define ws2812_set_color ws2812_rgb_set_color
+#define ws2812_set_color_all ws2812_rgb_set_color_all
+#define ws2812_flush ws2812_rgb_flush
 
 
 #include "ws2812_bitbang.c"
 #include "ws2812_bitbang.c"
 
 
 const rgblight_driver_t rgblight_driver = {
 const rgblight_driver_t rgblight_driver = {
-    .init    = ws2812_init,
-    .setleds = ws2812_setleds,
+    .init          = ws2812_init,
+    .set_color     = ws2812_set_color,
+    .set_color_all = ws2812_set_color_all,
+    .flush         = ws2812_flush,
 };
 };
 #endif
 #endif
 
 

+ 1 - 1
keyboards/xelus/dawn60/rev1/config.h

@@ -42,7 +42,7 @@
 #define RGB_BACKLIGHT_DAWN60
 #define RGB_BACKLIGHT_DAWN60
 
 
 //RGB Underglow defines
 //RGB Underglow defines
-#define WS2812_LED_TOTAL 20
+#define WS2812_LED_COUNT 20
 
 
 #define RGB_UNDERGLOW_ALPHA_TOP_START 0
 #define RGB_UNDERGLOW_ALPHA_TOP_START 0
 #define RGB_UNDERGLOW_ALPHA_TOP_END   6   
 #define RGB_UNDERGLOW_ALPHA_TOP_END   6   

+ 2 - 2
keyboards/xelus/dawn60/rev1_qmk/config.h

@@ -16,14 +16,14 @@
 #pragma once
 #pragma once
 
 
 //RGB Underglow defines
 //RGB Underglow defines
-#define WS2812_LED_TOTAL 20
+#define WS2812_LED_COUNT 20
 
 
 //RGB Matrix defines
 //RGB Matrix defines
 #define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND
 #define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND
 #define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_SDA
 #define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_SDA
 #define IS31FL3731_LED_COUNT 64
 #define IS31FL3731_LED_COUNT 64
 
 
-#define RGB_MATRIX_LED_COUNT (IS31FL3731_LED_COUNT + WS2812_LED_TOTAL)
+#define RGB_MATRIX_LED_COUNT (IS31FL3731_LED_COUNT + WS2812_LED_COUNT)
 
 
 // enable/disable LEDs based on layout
 // enable/disable LEDs based on layout
 // switch between split backspace (1) or normal backspace(0)
 // switch between split backspace (1) or normal backspace(0)

+ 3 - 11
keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c

@@ -23,8 +23,6 @@
 #include "ws2812.h"
 #include "ws2812.h"
 
 
 #ifdef RGB_MATRIX_ENABLE
 #ifdef RGB_MATRIX_ENABLE
-rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL];
-
 const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
 const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
 /* Refer to IS31 manual for these locations
 /* Refer to IS31 manual for these locations
  *   driver
  *   driver
@@ -161,26 +159,20 @@ static void init(void) {
 static void flush(void) {
 static void flush(void) {
     is31fl3731_update_pwm_buffers(0);
     is31fl3731_update_pwm_buffers(0);
     is31fl3731_update_pwm_buffers(1);
     is31fl3731_update_pwm_buffers(1);
-    ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL);
+    ws2812_flush();
 }
 }
 
 
 static void set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
 static void set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
     if (index < IS31FL3731_LED_COUNT) {
     if (index < IS31FL3731_LED_COUNT) {
         is31fl3731_set_color(index, red, green, blue);
         is31fl3731_set_color(index, red, green, blue);
     } else {
     } else {
-        rgb_matrix_ws2812_array[index - IS31FL3731_LED_COUNT].r = red;
-        rgb_matrix_ws2812_array[index - IS31FL3731_LED_COUNT].g = green;
-        rgb_matrix_ws2812_array[index - IS31FL3731_LED_COUNT].b = blue;
+        ws2812_set_color(index - IS31FL3731_LED_COUNT, red, green, blue);
     }
     }
 }
 }
 
 
 static void set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
 static void set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
     is31fl3731_set_color_all( red, green, blue );
     is31fl3731_set_color_all( red, green, blue );
-    for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) {
-        rgb_matrix_ws2812_array[i].r = red;
-        rgb_matrix_ws2812_array[i].g = green;
-        rgb_matrix_ws2812_array[i].b = blue;
-    }
+    ws2812_set_color_all( red, green, blue );
 }
 }
 
 
 
 

+ 3 - 0
keyboards/xiudi/xd002/keymaps/rgb_lite/config.h

@@ -0,0 +1,3 @@
+#pragma once
+
+#define WS2812_LED_COUNT 2

+ 3 - 3
keyboards/xiudi/xd002/keymaps/rgb_lite/rgblite.h

@@ -7,9 +7,9 @@ static inline void rgblite_init(void) {
     ws2812_init();
     ws2812_init();
 }
 }
 
 
-static inline void rgblite_setrgb(uint8_t _r, uint8_t _g, uint8_t _b) {
-    rgb_led_t leds[RGBLIGHT_LED_COUNT] = {{.r = _r, .g = _g, .b = _b}, {.r = _r, .g = _g, .b = _b}};
-    ws2812_setleds(leds, RGBLIGHT_LED_COUNT);
+static inline void rgblite_setrgb(uint8_t r, uint8_t g, uint8_t b) {
+    ws2812_set_color_all(r, g, b);
+    ws2812_flush();
 }
 }
 
 
 static void rgblite_increase_hue(void) {
 static void rgblite_increase_hue(void) {

+ 30 - 22
platforms/avr/drivers/ws2812_bitbang.c

@@ -28,28 +28,6 @@
 
 
 #define pinmask(pin) (_BV((pin)&0xF))
 #define pinmask(pin) (_BV((pin)&0xF))
 
 
-/*
- * Forward declare internal functions
- *
- * The functions take a byte-array and send to the data output as WS2812 bitstream.
- * The length is the number of bytes to send - three per LED.
- */
-
-static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t masklo, uint8_t maskhi);
-
-void ws2812_init(void) {
-    DDRx_ADDRESS(WS2812_DI_PIN) |= pinmask(WS2812_DI_PIN);
-}
-
-void ws2812_setleds(rgb_led_t *ledarray, uint16_t number_of_leds) {
-    uint8_t masklo = ~(pinmask(WS2812_DI_PIN)) & PORTx_ADDRESS(WS2812_DI_PIN);
-    uint8_t maskhi = pinmask(WS2812_DI_PIN) | PORTx_ADDRESS(WS2812_DI_PIN);
-
-    ws2812_sendarray_mask((uint8_t *)ledarray, number_of_leds * sizeof(rgb_led_t), masklo, maskhi);
-
-    _delay_us(WS2812_TRST_US);
-}
-
 /*
 /*
   This routine writes an array of bytes with RGB values to the Dataout pin
   This routine writes an array of bytes with RGB values to the Dataout pin
   using the fast 800kHz clockless WS2811/2812 protocol.
   using the fast 800kHz clockless WS2811/2812 protocol.
@@ -172,3 +150,33 @@ static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t
 
 
     SREG = sreg_prev;
     SREG = sreg_prev;
 }
 }
+
+ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
+
+void ws2812_init(void) {
+    DDRx_ADDRESS(WS2812_DI_PIN) |= pinmask(WS2812_DI_PIN);
+}
+
+void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    ws2812_leds[index].r = red;
+    ws2812_leds[index].g = green;
+    ws2812_leds[index].b = blue;
+#if defined(WS2812_RGBW)
+    ws2812_rgb_to_rgbw(&ws2812_leds[index]);
+#endif
+}
+
+void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
+        ws2812_set_color(i, red, green, blue);
+    }
+}
+
+void ws2812_flush(void) {
+    uint8_t masklo = ~(pinmask(WS2812_DI_PIN)) & PORTx_ADDRESS(WS2812_DI_PIN);
+    uint8_t maskhi = pinmask(WS2812_DI_PIN) | PORTx_ADDRESS(WS2812_DI_PIN);
+
+    ws2812_sendarray_mask((uint8_t *)ws2812_leds, WS2812_LED_COUNT * sizeof(ws2812_led_t), masklo, maskhi);
+
+    _delay_us(WS2812_TRST_US);
+}

+ 19 - 3
platforms/avr/drivers/ws2812_i2c.c

@@ -1,3 +1,6 @@
+// Copyright 2024 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 #include "ws2812.h"
 #include "ws2812.h"
 #include "i2c_master.h"
 #include "i2c_master.h"
 
 
@@ -13,11 +16,24 @@
 #    define WS2812_I2C_TIMEOUT 100
 #    define WS2812_I2C_TIMEOUT 100
 #endif
 #endif
 
 
+ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
+
 void ws2812_init(void) {
 void ws2812_init(void) {
     i2c_init();
     i2c_init();
 }
 }
 
 
-// Setleds for standard RGB
-void ws2812_setleds(rgb_led_t *ledarray, uint16_t leds) {
-    i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ledarray, sizeof(rgb_led_t) * leds, WS2812_I2C_TIMEOUT);
+void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    ws2812_leds[index].r = red;
+    ws2812_leds[index].g = green;
+    ws2812_leds[index].b = blue;
+}
+
+void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
+        ws2812_set_color(i, red, green, blue);
+    }
+}
+
+void ws2812_flush(void) {
+    i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ws2812_leds, WS2812_LED_COUNT * sizeof(ws2812_led_t), WS2812_I2C_TIMEOUT);
 }
 }

+ 22 - 5
platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c

@@ -266,19 +266,36 @@ static inline void sync_ws2812_transfer(void) {
     busy_wait_until(LAST_TRANSFER);
     busy_wait_until(LAST_TRANSFER);
 }
 }
 
 
-void ws2812_setleds(rgb_led_t* ledarray, uint16_t leds) {
+ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
+
+void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    ws2812_leds[index].r = red;
+    ws2812_leds[index].g = green;
+    ws2812_leds[index].b = blue;
+#if defined(WS2812_RGBW)
+    ws2812_rgb_to_rgbw(&ws2812_leds[index]);
+#endif
+}
+
+void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
+        ws2812_set_color(i, red, green, blue);
+    }
+}
+
+void ws2812_flush(void) {
     sync_ws2812_transfer();
     sync_ws2812_transfer();
 
 
-    for (int i = 0; i < leds; i++) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
 #if defined(WS2812_RGBW)
 #if defined(WS2812_RGBW)
-        WS2812_BUFFER[i] = rgbw8888_to_u32(ledarray[i].r, ledarray[i].g, ledarray[i].b, ledarray[i].w);
+        WS2812_BUFFER[i] = rgbw8888_to_u32(ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b, ws2812_leds[i].w);
 #else
 #else
-        WS2812_BUFFER[i] = rgbw8888_to_u32(ledarray[i].r, ledarray[i].g, ledarray[i].b, 0);
+        WS2812_BUFFER[i] = rgbw8888_to_u32(ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b, 0);
 #endif
 #endif
     }
     }
 
 
     dmaChannelSetSourceX(dma_channel, (uint32_t)WS2812_BUFFER);
     dmaChannelSetSourceX(dma_channel, (uint32_t)WS2812_BUFFER);
-    dmaChannelSetCounterX(dma_channel, leds);
+    dmaChannelSetCounterX(dma_channel, WS2812_LED_COUNT);
     dmaChannelSetModeX(dma_channel, RP_DMA_MODE_WS2812);
     dmaChannelSetModeX(dma_channel, RP_DMA_MODE_WS2812);
     dmaChannelEnableX(dma_channel);
     dmaChannelEnableX(dma_channel);
 }
 }

+ 29 - 13
platforms/chibios/drivers/ws2812_bitbang.c

@@ -76,33 +76,49 @@ void sendByte(uint8_t byte) {
     }
     }
 }
 }
 
 
+ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
+
 void ws2812_init(void) {
 void ws2812_init(void) {
     palSetLineMode(WS2812_DI_PIN, WS2812_OUTPUT_MODE);
     palSetLineMode(WS2812_DI_PIN, WS2812_OUTPUT_MODE);
 }
 }
 
 
-// Setleds for standard RGB
-void ws2812_setleds(rgb_led_t *ledarray, uint16_t leds) {
+void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    ws2812_leds[index].r = red;
+    ws2812_leds[index].g = green;
+    ws2812_leds[index].b = blue;
+#if defined(WS2812_RGBW)
+    ws2812_rgb_to_rgbw(&ws2812_leds[index]);
+#endif
+}
+
+void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
+        ws2812_set_color(i, red, green, blue);
+    }
+}
+
+void ws2812_flush(void) {
     // this code is very time dependent, so we need to disable interrupts
     // this code is very time dependent, so we need to disable interrupts
     chSysLock();
     chSysLock();
 
 
-    for (uint8_t i = 0; i < leds; i++) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
         // WS2812 protocol dictates grb order
         // WS2812 protocol dictates grb order
 #if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
 #if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
-        sendByte(ledarray[i].g);
-        sendByte(ledarray[i].r);
-        sendByte(ledarray[i].b);
+        sendByte(ws2812_leds[i].g);
+        sendByte(ws2812_leds[i].r);
+        sendByte(ws2812_leds[i].b);
 #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
 #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
-        sendByte(ledarray[i].r);
-        sendByte(ledarray[i].g);
-        sendByte(ledarray[i].b);
+        sendByte(ws2812_leds[i].r);
+        sendByte(ws2812_leds[i].g);
+        sendByte(ws2812_leds[i].b);
 #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
 #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
-        sendByte(ledarray[i].b);
-        sendByte(ledarray[i].g);
-        sendByte(ledarray[i].r);
+        sendByte(ws2812_leds[i].b);
+        sendByte(ws2812_leds[i].g);
+        sendByte(ws2812_leds[i].r);
 #endif
 #endif
 
 
 #ifdef WS2812_RGBW
 #ifdef WS2812_RGBW
-        sendByte(ledarray[i].w);
+        sendByte(ws2812_leds[i].w);
 #endif
 #endif
     }
     }
 
 

+ 22 - 6
platforms/chibios/drivers/ws2812_pwm.c

@@ -387,13 +387,29 @@ void ws2812_write_led_rgbw(uint16_t led_number, uint8_t r, uint8_t g, uint8_t b,
     }
     }
 }
 }
 
 
-// Setleds for standard RGB
-void ws2812_setleds(rgb_led_t* ledarray, uint16_t leds) {
-    for (uint16_t i = 0; i < leds; i++) {
-#ifdef WS2812_RGBW
-        ws2812_write_led_rgbw(i, ledarray[i].r, ledarray[i].g, ledarray[i].b, ledarray[i].w);
+ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
+
+void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    ws2812_leds[index].r = red;
+    ws2812_leds[index].g = green;
+    ws2812_leds[index].b = blue;
+#if defined(WS2812_RGBW)
+    ws2812_rgb_to_rgbw(&ws2812_leds[index]);
+#endif
+}
+
+void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
+        ws2812_set_color(i, red, green, blue);
+    }
+}
+
+void ws2812_flush(void) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
+#if defined(WS2812_RGBW)
+        ws2812_write_led_rgbw(i, ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b, ws2812_leds[i].w);
 #else
 #else
-        ws2812_write_led(i, ledarray[i].r, ledarray[i].g, ledarray[i].b);
+        ws2812_write_led(i, ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b);
 #endif
 #endif
     }
     }
 }
 }

+ 21 - 4
platforms/chibios/drivers/ws2812_spi.c

@@ -106,7 +106,7 @@ static uint8_t get_protocol_eq(uint8_t data, int pos) {
     return eq;
     return eq;
 }
 }
 
 
-static void set_led_color_rgb(rgb_led_t color, int pos) {
+static void set_led_color_rgb(ws2812_led_t color, int pos) {
     uint8_t* tx_start = &txbuf[PREAMBLE_SIZE];
     uint8_t* tx_start = &txbuf[PREAMBLE_SIZE];
 
 
 #if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
 #if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
@@ -137,6 +137,8 @@ static void set_led_color_rgb(rgb_led_t color, int pos) {
 #endif
 #endif
 }
 }
 
 
+ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
+
 void ws2812_init(void) {
 void ws2812_init(void) {
     palSetLineMode(WS2812_DI_PIN, WS2812_MOSI_OUTPUT_MODE);
     palSetLineMode(WS2812_DI_PIN, WS2812_MOSI_OUTPUT_MODE);
 
 
@@ -187,9 +189,24 @@ void ws2812_init(void) {
 #endif
 #endif
 }
 }
 
 
-void ws2812_setleds(rgb_led_t* ledarray, uint16_t leds) {
-    for (uint8_t i = 0; i < leds; i++) {
-        set_led_color_rgb(ledarray[i], i);
+void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
+    ws2812_leds[index].r = red;
+    ws2812_leds[index].g = green;
+    ws2812_leds[index].b = blue;
+#if defined(WS2812_RGBW)
+    ws2812_rgb_to_rgbw(&ws2812_leds[index]);
+#endif
+}
+
+void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
+        ws2812_set_color(i, red, green, blue);
+    }
+}
+
+void ws2812_flush(void) {
+    for (int i = 0; i < WS2812_LED_COUNT; i++) {
+        set_led_color_rgb(ws2812_leds[i], i);
     }
     }
 
 
     // Send async - each led takes ~0.03ms, 50 leds ~1.5ms, animations flushing faster than send will cause issues.
     // Send async - each led takes ~0.03ms, 50 leds ~1.5ms, animations flushing faster than send will cause issues.

+ 0 - 11
quantum/color.c

@@ -108,14 +108,3 @@ RGB hsv_to_rgb(HSV hsv) {
 RGB hsv_to_rgb_nocie(HSV hsv) {
 RGB hsv_to_rgb_nocie(HSV hsv) {
     return hsv_to_rgb_impl(hsv, false);
     return hsv_to_rgb_impl(hsv, false);
 }
 }
-
-#ifdef WS2812_RGBW
-void convert_rgb_to_rgbw(rgb_led_t *led) {
-    // Determine lowest value in all three colors, put that into
-    // the white channel and then shift all colors by that amount
-    led->w = MIN(led->r, MIN(led->g, led->b));
-    led->r -= led->w;
-    led->g -= led->w;
-    led->b -= led->w;
-}
-#endif

+ 0 - 24
quantum/color.h

@@ -74,31 +74,10 @@
 
 
 // clang-format on
 // clang-format on
 
 
-#define WS2812_BYTE_ORDER_RGB 0
-#define WS2812_BYTE_ORDER_GRB 1
-#define WS2812_BYTE_ORDER_BGR 2
-
-#ifndef WS2812_BYTE_ORDER
-#    define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB
-#endif
-
 typedef struct PACKED rgb_led_t {
 typedef struct PACKED rgb_led_t {
-#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
-    uint8_t g;
-    uint8_t r;
-    uint8_t b;
-#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
     uint8_t r;
     uint8_t r;
     uint8_t g;
     uint8_t g;
     uint8_t b;
     uint8_t b;
-#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
-    uint8_t b;
-    uint8_t g;
-    uint8_t r;
-#endif
-#ifdef WS2812_RGBW
-    uint8_t w;
-#endif
 } rgb_led_t;
 } rgb_led_t;
 
 
 typedef rgb_led_t RGB;
 typedef rgb_led_t RGB;
@@ -111,6 +90,3 @@ typedef struct PACKED HSV {
 
 
 RGB hsv_to_rgb(HSV hsv);
 RGB hsv_to_rgb(HSV hsv);
 RGB hsv_to_rgb_nocie(HSV hsv);
 RGB hsv_to_rgb_nocie(HSV hsv);
-#ifdef WS2812_RGBW
-void convert_rgb_to_rgbw(rgb_led_t *led);
-#endif

+ 10 - 1
quantum/led_matrix/led_matrix.c

@@ -139,11 +139,20 @@ void led_matrix_update_pwm_buffers(void) {
     led_matrix_driver.flush();
     led_matrix_driver.flush();
 }
 }
 
 
+__attribute__((weak)) int led_matrix_led_index(int index) {
+#if defined(LED_MATRIX_SPLIT)
+    if (!is_keyboard_left() && index >= k_led_matrix_split[0]) {
+        return index - k_led_matrix_split[0];
+    }
+#endif
+    return index;
+}
+
 void led_matrix_set_value(int index, uint8_t value) {
 void led_matrix_set_value(int index, uint8_t value) {
 #ifdef USE_CIE1931_CURVE
 #ifdef USE_CIE1931_CURVE
     value = pgm_read_byte(&CIE1931_CURVE[value]);
     value = pgm_read_byte(&CIE1931_CURVE[value]);
 #endif
 #endif
-    led_matrix_driver.set_value(index, value);
+    led_matrix_driver.set_value(led_matrix_led_index(index), value);
 }
 }
 
 
 void led_matrix_set_value_all(uint8_t value) {
 void led_matrix_set_value_all(uint8_t value) {

+ 2 - 0
quantum/led_matrix/led_matrix.h

@@ -121,6 +121,8 @@ void eeconfig_debug_led_matrix(void);
 uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
 uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
 uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
 uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
 
 
+int led_matrix_led_index(int index);
+
 void led_matrix_set_value(int index, uint8_t value);
 void led_matrix_set_value(int index, uint8_t value);
 void led_matrix_set_value_all(uint8_t value);
 void led_matrix_set_value_all(uint8_t value);
 
 

+ 10 - 1
quantum/rgb_matrix/rgb_matrix.c

@@ -143,8 +143,17 @@ void rgb_matrix_update_pwm_buffers(void) {
     rgb_matrix_driver.flush();
     rgb_matrix_driver.flush();
 }
 }
 
 
+__attribute__((weak)) int rgb_matrix_led_index(int index) {
+#if defined(RGB_MATRIX_SPLIT)
+    if (!is_keyboard_left() && index >= k_rgb_matrix_split[0]) {
+        return index - k_rgb_matrix_split[0];
+    }
+#endif
+    return index;
+}
+
 void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
 void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
-    rgb_matrix_driver.set_color(index, red, green, blue);
+    rgb_matrix_driver.set_color(rgb_matrix_led_index(index), red, green, blue);
 }
 }
 
 
 void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
 void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {

+ 2 - 0
quantum/rgb_matrix/rgb_matrix.h

@@ -145,6 +145,8 @@ void eeconfig_update_rgb_matrix(void);
 uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
 uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
 uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
 uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
 
 
+int rgb_matrix_led_index(int index);
+
 void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
 void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
 void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
 void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
 
 

+ 4 - 54
quantum/rgb_matrix/rgb_matrix_drivers.c

@@ -146,61 +146,11 @@ const rgb_matrix_driver_t rgb_matrix_driver = {
 #        pragma message "You need to use a custom driver, or re-implement the WS2812 driver to use a different configuration."
 #        pragma message "You need to use a custom driver, or re-implement the WS2812 driver to use a different configuration."
 #    endif
 #    endif
 
 
-// LED color buffer
-rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_COUNT];
-bool      ws2812_dirty = false;
-
-static void init(void) {
-    ws2812_init();
-    ws2812_dirty = false;
-}
-
-static void flush(void) {
-    if (ws2812_dirty) {
-        ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_COUNT);
-        ws2812_dirty = false;
-    }
-}
-
-// Set an led in the buffer to a color
-static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) {
-#    if defined(RGB_MATRIX_SPLIT)
-    const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;
-    if (!is_keyboard_left()) {
-        if (i >= k_rgb_matrix_split[0]) {
-            i -= k_rgb_matrix_split[0];
-        } else {
-            return;
-        }
-    } else if (i >= k_rgb_matrix_split[0]) {
-        return;
-    }
-#    endif
-
-    if (rgb_matrix_ws2812_array[i].r == r && rgb_matrix_ws2812_array[i].g == g && rgb_matrix_ws2812_array[i].b == b) {
-        return;
-    }
-
-    ws2812_dirty                 = true;
-    rgb_matrix_ws2812_array[i].r = r;
-    rgb_matrix_ws2812_array[i].g = g;
-    rgb_matrix_ws2812_array[i].b = b;
-#    ifdef WS2812_RGBW
-    convert_rgb_to_rgbw(&rgb_matrix_ws2812_array[i]);
-#    endif
-}
-
-static void setled_all(uint8_t r, uint8_t g, uint8_t b) {
-    for (int i = 0; i < ARRAY_SIZE(rgb_matrix_ws2812_array); i++) {
-        setled(i, r, g, b);
-    }
-}
-
 const rgb_matrix_driver_t rgb_matrix_driver = {
 const rgb_matrix_driver_t rgb_matrix_driver = {
-    .init          = init,
-    .flush         = flush,
-    .set_color     = setled,
-    .set_color_all = setled_all,
+    .init          = ws2812_init,
+    .flush         = ws2812_flush,
+    .set_color     = ws2812_set_color,
+    .set_color_all = ws2812_set_color_all,
 };
 };
 
 
 #endif
 #endif

+ 45 - 107
quantum/rgblight/rgblight.c

@@ -115,11 +115,6 @@ static bool pre_suspend_enabled;
 animation_status_t animation_status = {};
 animation_status_t animation_status = {};
 #endif
 #endif
 
 
-#ifndef LED_ARRAY
-rgb_led_t led[RGBLIGHT_LED_COUNT];
-#    define LED_ARRAY led
-#endif
-
 #ifdef RGBLIGHT_LAYERS
 #ifdef RGBLIGHT_LAYERS
 rgblight_segment_t const *const *rgblight_layers = NULL;
 rgblight_segment_t const *const *rgblight_layers = NULL;
 
 
@@ -145,23 +140,26 @@ __attribute__((weak)) RGB rgblight_hsv_to_rgb(HSV hsv) {
     return hsv_to_rgb(hsv);
     return hsv_to_rgb(hsv);
 }
 }
 
 
-void setrgb(uint8_t r, uint8_t g, uint8_t b, rgb_led_t *led1) {
-    led1->r = r;
-    led1->g = g;
-    led1->b = b;
-#ifdef WS2812_RGBW
-    led1->w = 0;
+uint8_t rgblight_led_index(uint8_t index) {
+#if defined(RGBLIGHT_LED_MAP)
+    return pgm_read_byte(&led_map[index]) - rgblight_ranges.clipping_start_pos;
+#else
+    return index - rgblight_ranges.clipping_start_pos;
 #endif
 #endif
 }
 }
 
 
-void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, rgb_led_t *led1) {
+void setrgb(uint8_t r, uint8_t g, uint8_t b, int index) {
+    rgblight_driver.set_color(rgblight_led_index(index), r, g, b);
+}
+
+void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, int index) {
     HSV hsv = {hue, sat, val};
     HSV hsv = {hue, sat, val};
     RGB rgb = rgblight_hsv_to_rgb(hsv);
     RGB rgb = rgblight_hsv_to_rgb(hsv);
-    setrgb(rgb.r, rgb.g, rgb.b, led1);
+    setrgb(rgb.r, rgb.g, rgb.b, index);
 }
 }
 
 
-void sethsv(uint8_t hue, uint8_t sat, uint8_t val, rgb_led_t *led1) {
-    sethsv_raw(hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val, led1);
+void sethsv(uint8_t hue, uint8_t sat, uint8_t val, int index) {
+    sethsv_raw(hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val, index);
 }
 }
 
 
 void rgblight_check_config(void) {
 void rgblight_check_config(void) {
@@ -515,9 +513,8 @@ void rgblight_decrease_speed_noeeprom(void) {
 
 
 void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) {
 void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) {
     if (rgblight_config.enable) {
     if (rgblight_config.enable) {
-        rgb_led_t tmp_led;
-        sethsv(hue, sat, val, &tmp_led);
-        rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
+        RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
+        rgblight_setrgb(rgb.r, rgb.g, rgb.b);
     }
     }
 }
 }
 
 
@@ -531,13 +528,12 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w
         rgblight_status.base_mode = mode_base_table[rgblight_config.mode];
         rgblight_status.base_mode = mode_base_table[rgblight_config.mode];
         if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) {
         if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) {
             // same static color
             // same static color
-            rgb_led_t tmp_led;
 #ifdef RGBLIGHT_LAYERS_RETAIN_VAL
 #ifdef RGBLIGHT_LAYERS_RETAIN_VAL
             // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val
             // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val
             rgblight_config.val = val;
             rgblight_config.val = val;
 #endif
 #endif
-            sethsv(hue, sat, val, &tmp_led);
-            rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
+            RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
+            rgblight_setrgb(rgb.r, rgb.g, rgb.b);
         } else {
         } else {
             // all LEDs in same color
             // all LEDs in same color
             if (1 == 0) { // dummy
             if (1 == 0) { // dummy
@@ -575,7 +571,7 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w
                         _hue = hue - _hue;
                         _hue = hue - _hue;
                     }
                     }
                     dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range);
                     dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range);
-                    sethsv(_hue, sat, val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]);
+                    sethsv(_hue, sat, val, i + rgblight_ranges.effect_start_pos);
                 }
                 }
 #    ifdef RGBLIGHT_LAYERS_RETAIN_VAL
 #    ifdef RGBLIGHT_LAYERS_RETAIN_VAL
                 // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val
                 // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val
@@ -649,12 +645,7 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
     }
     }
 
 
     for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
     for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
-        led[i].r = r;
-        led[i].g = g;
-        led[i].b = b;
-#ifdef WS2812_RGBW
-        led[i].w = 0;
-#endif
+        rgblight_driver.set_color(rgblight_led_index(i), r, g, b);
     }
     }
     rgblight_set();
     rgblight_set();
 }
 }
@@ -664,12 +655,7 @@ void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) {
         return;
         return;
     }
     }
 
 
-    led[index].r = r;
-    led[index].g = g;
-    led[index].b = b;
-#ifdef WS2812_RGBW
-    led[index].w = 0;
-#endif
+    rgblight_driver.set_color(rgblight_led_index(index), r, g, b);
     rgblight_set();
     rgblight_set();
 }
 }
 
 
@@ -678,9 +664,8 @@ void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index) {
         return;
         return;
     }
     }
 
 
-    rgb_led_t tmp_led;
-    sethsv(hue, sat, val, &tmp_led);
-    rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index);
+    RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
+    rgblight_setrgb_at(rgb.r, rgb.g, rgb.b, index);
 }
 }
 
 
 #if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE)
 #if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE)
@@ -701,12 +686,7 @@ void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8
     }
     }
 
 
     for (uint8_t i = start; i < end; i++) {
     for (uint8_t i = start; i < end; i++) {
-        led[i].r = r;
-        led[i].g = g;
-        led[i].b = b;
-#ifdef WS2812_RGBW
-        led[i].w = 0;
-#endif
+        rgblight_driver.set_color(rgblight_led_index(i), r, g, b);
     }
     }
     rgblight_set();
     rgblight_set();
 }
 }
@@ -716,9 +696,8 @@ void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start,
         return;
         return;
     }
     }
 
 
-    rgb_led_t tmp_led;
-    sethsv(hue, sat, val, &tmp_led);
-    rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end);
+    RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
+    rgblight_setrgb_range(rgb.r, rgb.g, rgb.b, start, end);
 }
 }
 
 
 #ifndef RGBLIGHT_SPLIT
 #ifndef RGBLIGHT_SPLIT
@@ -785,12 +764,12 @@ static void rgblight_layers_write(void) {
                 break; // No more segments
                 break; // No more segments
             }
             }
             // Write segment.count LEDs
             // Write segment.count LEDs
-            rgb_led_t *const limit = &led[MIN(segment.index + segment.count, RGBLIGHT_LED_COUNT)];
-            for (rgb_led_t *led_ptr = &led[segment.index]; led_ptr < limit; led_ptr++) {
+            int limit = MIN(segment.index + segment.count, RGBLIGHT_LED_COUNT);
+            for (int i = segment.index; i < limit; i++) {
 #    ifdef RGBLIGHT_LAYERS_RETAIN_VAL
 #    ifdef RGBLIGHT_LAYERS_RETAIN_VAL
-                sethsv(segment.hue, segment.sat, current_val, led_ptr);
+                sethsv(segment.hue, segment.sat, current_val, i);
 #    else
 #    else
-                sethsv(segment.hue, segment.sat, segment.val, led_ptr);
+                sethsv(segment.hue, segment.sat, segment.val, i);
 #    endif
 #    endif
             }
             }
             segment_ptr++;
             segment_ptr++;
@@ -897,17 +876,9 @@ void rgblight_wakeup(void) {
 #endif
 #endif
 
 
 void rgblight_set(void) {
 void rgblight_set(void) {
-    rgb_led_t *start_led;
-    uint8_t    num_leds = rgblight_ranges.clipping_num_leds;
-
     if (!rgblight_config.enable) {
     if (!rgblight_config.enable) {
         for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
         for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
-            led[i].r = 0;
-            led[i].g = 0;
-            led[i].b = 0;
-#ifdef WS2812_RGBW
-            led[i].w = 0;
-#endif
+            rgblight_driver.set_color(rgblight_led_index(i), 0, 0, 0);
         }
         }
     }
     }
 
 
@@ -923,22 +894,7 @@ void rgblight_set(void) {
     }
     }
 #endif
 #endif
 
 
-#ifdef RGBLIGHT_LED_MAP
-    rgb_led_t led0[RGBLIGHT_LED_COUNT];
-    for (uint8_t i = 0; i < RGBLIGHT_LED_COUNT; i++) {
-        led0[i] = led[pgm_read_byte(&led_map[i])];
-    }
-    start_led = led0 + rgblight_ranges.clipping_start_pos;
-#else
-    start_led = led + rgblight_ranges.clipping_start_pos;
-#endif
-
-#ifdef WS2812_RGBW
-    for (uint8_t i = 0; i < num_leds; i++) {
-        convert_rgb_to_rgbw(&start_led[i]);
-    }
-#endif
-    rgblight_driver.setleds(start_led, num_leds);
+    rgblight_driver.flush();
 }
 }
 
 
 #ifdef RGBLIGHT_SPLIT
 #ifdef RGBLIGHT_SPLIT
@@ -1222,7 +1178,7 @@ void rgblight_effect_rainbow_swirl(animation_status_t *anim) {
 
 
     for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
     for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
         hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / rgblight_ranges.effect_num_leds * i + anim->current_hue);
         hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / rgblight_ranges.effect_num_leds * i + anim->current_hue);
-        sethsv(hue, rgblight_config.sat, rgblight_config.val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]);
+        sethsv(hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos);
     }
     }
     rgblight_set();
     rgblight_set();
 
 
@@ -1259,13 +1215,8 @@ void rgblight_effect_snake(animation_status_t *anim) {
 #    endif
 #    endif
 
 
     for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
     for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
-        rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos;
-        ledp->r         = 0;
-        ledp->g         = 0;
-        ledp->b         = 0;
-#    ifdef WS2812_RGBW
-        ledp->w = 0;
-#    endif
+        rgblight_driver.set_color(rgblight_led_index(i + rgblight_ranges.effect_start_pos), 0, 0, 0);
+
         for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
         for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
             k = pos + j * increment;
             k = pos + j * increment;
             if (k > RGBLIGHT_LED_COUNT) {
             if (k > RGBLIGHT_LED_COUNT) {
@@ -1275,7 +1226,7 @@ void rgblight_effect_snake(animation_status_t *anim) {
                 k = k + rgblight_ranges.effect_num_leds;
                 k = k + rgblight_ranges.effect_num_leds;
             }
             }
             if (i == k) {
             if (i == k) {
-                sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), ledp);
+                sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), i + rgblight_ranges.effect_start_pos);
             }
             }
         }
         }
     }
     }
@@ -1320,26 +1271,16 @@ void rgblight_effect_knight(animation_status_t *anim) {
 #    endif
 #    endif
     // Set all the LEDs to 0
     // Set all the LEDs to 0
     for (i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
     for (i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
-        led[i].r = 0;
-        led[i].g = 0;
-        led[i].b = 0;
-#    ifdef WS2812_RGBW
-        led[i].w = 0;
-#    endif
+        rgblight_driver.set_color(rgblight_led_index(i), 0, 0, 0);
     }
     }
     // Determine which LEDs should be lit up
     // Determine which LEDs should be lit up
     for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
     for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
         cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % rgblight_ranges.effect_num_leds + rgblight_ranges.effect_start_pos;
         cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % rgblight_ranges.effect_num_leds + rgblight_ranges.effect_start_pos;
 
 
         if (i >= low_bound && i <= high_bound) {
         if (i >= low_bound && i <= high_bound) {
-            sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (rgb_led_t *)&led[cur]);
+            sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, cur);
         } else {
         } else {
-            led[cur].r = 0;
-            led[cur].g = 0;
-            led[cur].b = 0;
-#    ifdef WS2812_RGBW
-            led[cur].w = 0;
-#    endif
+            rgblight_driver.set_color(rgblight_led_index(cur), 0, 0, 0);
         }
         }
     }
     }
     rgblight_set();
     rgblight_set();
@@ -1384,7 +1325,7 @@ void rgblight_effect_christmas(animation_status_t *anim) {
 
 
     for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
     for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
         uint8_t local_hue = (i / RGBLIGHT_EFFECT_CHRISTMAS_STEP) % 2 ? hue : hue_green - hue;
         uint8_t local_hue = (i / RGBLIGHT_EFFECT_CHRISTMAS_STEP) % 2 ? hue : hue_green - hue;
-        sethsv(local_hue, rgblight_config.sat, val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]);
+        sethsv(local_hue, rgblight_config.sat, val, i + rgblight_ranges.effect_start_pos);
     }
     }
     rgblight_set();
     rgblight_set();
 
 
@@ -1407,9 +1348,8 @@ void rgblight_effect_rgbtest(animation_status_t *anim) {
     uint8_t        b;
     uint8_t        b;
 
 
     if (maxval == 0) {
     if (maxval == 0) {
-        rgb_led_t tmp_led;
-        sethsv(0, 255, RGBLIGHT_LIMIT_VAL, &tmp_led);
-        maxval = tmp_led.r;
+        RGB rgb = hsv_to_rgb((HSV){0, 255, RGBLIGHT_LIMIT_VAL});
+        maxval  = rgb.r;
     }
     }
     g = r = b = 0;
     g = r = b = 0;
     switch (anim->pos) {
     switch (anim->pos) {
@@ -1431,13 +1371,12 @@ void rgblight_effect_rgbtest(animation_status_t *anim) {
 #ifdef RGBLIGHT_EFFECT_ALTERNATING
 #ifdef RGBLIGHT_EFFECT_ALTERNATING
 void rgblight_effect_alternating(animation_status_t *anim) {
 void rgblight_effect_alternating(animation_status_t *anim) {
     for (int i = 0; i < rgblight_ranges.effect_num_leds; i++) {
     for (int i = 0; i < rgblight_ranges.effect_num_leds; i++) {
-        rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos;
         if (i < rgblight_ranges.effect_num_leds / 2 && anim->pos) {
         if (i < rgblight_ranges.effect_num_leds / 2 && anim->pos) {
-            sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
+            sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos);
         } else if (i >= rgblight_ranges.effect_num_leds / 2 && !anim->pos) {
         } else if (i >= rgblight_ranges.effect_num_leds / 2 && !anim->pos) {
-            sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
+            sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos);
         } else {
         } else {
-            sethsv(rgblight_config.hue, rgblight_config.sat, 0, ledp);
+            sethsv(rgblight_config.hue, rgblight_config.sat, 0, i + rgblight_ranges.effect_start_pos);
         }
         }
     }
     }
     rgblight_set();
     rgblight_set();
@@ -1504,8 +1443,7 @@ void rgblight_effect_twinkle(animation_status_t *anim) {
             // This LED is off, and was NOT selected to start brightening
             // This LED is off, and was NOT selected to start brightening
         }
         }
 
 
-        rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos;
-        sethsv(c->h, c->s, c->v, ledp);
+        sethsv(c->h, c->s, c->v, i + rgblight_ranges.effect_start_pos);
     }
     }
 
 
     rgblight_set();
     rgblight_set();

+ 0 - 1
quantum/rgblight/rgblight.h

@@ -169,7 +169,6 @@ enum RGBLIGHT_EFFECT_MODE {
 #include "rgblight_drivers.h"
 #include "rgblight_drivers.h"
 #include "progmem.h"
 #include "progmem.h"
 #include "eeconfig.h"
 #include "eeconfig.h"
-#include "ws2812.h"
 #include "color.h"
 #include "color.h"
 
 
 #ifdef RGBLIGHT_LAYERS
 #ifdef RGBLIGHT_LAYERS

+ 8 - 12
quantum/rgblight/rgblight_drivers.c

@@ -7,24 +7,20 @@
 #    include "ws2812.h"
 #    include "ws2812.h"
 
 
 const rgblight_driver_t rgblight_driver = {
 const rgblight_driver_t rgblight_driver = {
-    .init    = ws2812_init,
-    .setleds = ws2812_setleds,
+    .init          = ws2812_init,
+    .set_color     = ws2812_set_color,
+    .set_color_all = ws2812_set_color_all,
+    .flush         = ws2812_flush,
 };
 };
 
 
 #elif defined(RGBLIGHT_APA102)
 #elif defined(RGBLIGHT_APA102)
 #    include "apa102.h"
 #    include "apa102.h"
 
 
-// Temporary shim
-static void apa102_setleds(rgb_led_t *ledarray, uint16_t number_of_leds) {
-    for (uint16_t i = 0; i < number_of_leds; i++) {
-        apa102_set_color(i, ledarray[i].r, ledarray[i].g, ledarray[i].b);
-    }
-    apa102_flush();
-}
-
 const rgblight_driver_t rgblight_driver = {
 const rgblight_driver_t rgblight_driver = {
-    .init    = apa102_init,
-    .setleds = apa102_setleds,
+    .init          = apa102_init,
+    .set_color     = apa102_set_color,
+    .set_color_all = apa102_set_color_all,
+    .flush         = apa102_flush,
 };
 };
 
 
 #endif
 #endif

+ 3 - 2
quantum/rgblight/rgblight_drivers.h

@@ -4,11 +4,12 @@
 #pragma once
 #pragma once
 
 
 #include <stdint.h>
 #include <stdint.h>
-#include "color.h"
 
 
 typedef struct {
 typedef struct {
     void (*init)(void);
     void (*init)(void);
-    void (*setleds)(rgb_led_t *ledarray, uint16_t number_of_leds);
+    void (*set_color)(int index, uint8_t red, uint8_t green, uint8_t blue);
+    void (*set_color_all)(uint8_t red, uint8_t green, uint8_t blue);
+    void (*flush)(void);
 } rgblight_driver_t;
 } rgblight_driver_t;
 
 
 extern const rgblight_driver_t rgblight_driver;
 extern const rgblight_driver_t rgblight_driver;