summaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/dip_switch.c57
-rw-r--r--quantum/dip_switch.h27
-rw-r--r--quantum/keyboard.c2
-rw-r--r--quantum/keyboard.h13
-rw-r--r--quantum/keymap_common.c12
-rw-r--r--quantum/keymap_extras/keymap_spanish_latin_america.h105
-rw-r--r--quantum/keymap_extras/sendstring_spanish_latin_america.h120
-rw-r--r--quantum/keymap_introspection.c18
-rw-r--r--quantum/keymap_introspection.h12
-rw-r--r--quantum/led_matrix/led_matrix.c23
-rw-r--r--quantum/led_matrix/led_matrix.h39
-rw-r--r--quantum/led_matrix/led_matrix_drivers.c2
-rw-r--r--quantum/led_matrix/led_matrix_drivers.h38
-rw-r--r--quantum/rgb_matrix/rgb_matrix.c19
-rw-r--r--quantum/rgb_matrix/rgb_matrix.h36
-rw-r--r--quantum/rgb_matrix/rgb_matrix_drivers.c6
-rw-r--r--quantum/rgb_matrix/rgb_matrix_drivers.h41
-rw-r--r--quantum/rgblight/rgblight.c33
-rw-r--r--quantum/rgblight/rgblight.h1
-rw-r--r--quantum/rgblight/rgblight_drivers.c20
-rw-r--r--quantum/rgblight/rgblight_drivers.h13
21 files changed, 486 insertions, 151 deletions
diff --git a/quantum/dip_switch.c b/quantum/dip_switch.c
index 6e254578d1..e901f3e0c4 100644
--- a/quantum/dip_switch.c
+++ b/quantum/dip_switch.c
@@ -19,8 +19,6 @@
#include <string.h> // for memcpy
#include "dip_switch.h"
-#include "gpio.h"
-#include "util.h"
#ifdef SPLIT_KEYBOARD
# include "split_common/split_util.h"
@@ -35,24 +33,17 @@
#endif
#ifdef DIP_SWITCH_PINS
-# define NUMBER_OF_DIP_SWITCHES (ARRAY_SIZE(dip_switch_pad))
static pin_t dip_switch_pad[] = DIP_SWITCH_PINS;
#endif
#ifdef DIP_SWITCH_MATRIX_GRID
-typedef struct matrix_index_t {
- uint8_t row;
- uint8_t col;
-} matrix_index_t;
-
-# define NUMBER_OF_DIP_SWITCHES (ARRAY_SIZE(dip_switch_pad))
-static matrix_index_t dip_switch_pad[] = DIP_SWITCH_MATRIX_GRID;
-extern bool peek_matrix(uint8_t row_index, uint8_t col_index, bool read_raw);
-static uint16_t scan_count;
+static matrix_intersection_t dip_switch_pad[] = DIP_SWITCH_MATRIX_GRID;
+extern bool peek_matrix(uint8_t row_index, uint8_t col_index, bool read_raw);
+static uint16_t scan_count;
#endif /* DIP_SWITCH_MATRIX_GRID */
-static bool dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0};
-static bool last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0};
+static bool dip_switch_state[NUM_DIP_SWITCHES] = {0};
+static bool last_dip_switch_state[NUM_DIP_SWITCHES] = {0};
__attribute__((weak)) bool dip_switch_update_user(uint8_t index, bool active) {
return true;
@@ -70,17 +61,39 @@ __attribute__((weak)) bool dip_switch_update_mask_kb(uint32_t state) {
return dip_switch_update_mask_user(state);
}
+#ifdef DIP_SWITCH_MAP_ENABLE
+# include "keymap_introspection.h"
+# include "action.h"
+
+# ifndef DIP_SWITCH_MAP_KEY_DELAY
+# define DIP_SWITCH_MAP_KEY_DELAY TAP_CODE_DELAY
+# endif
+
+static void dip_switch_exec_mapping(uint8_t index, bool on) {
+ // The delays below cater for Windows and its wonderful requirements.
+ action_exec(on ? MAKE_DIPSWITCH_ON_EVENT(index, true) : MAKE_DIPSWITCH_OFF_EVENT(index, true));
+# if DIP_SWITCH_MAP_KEY_DELAY > 0
+ wait_ms(DIP_SWITCH_MAP_KEY_DELAY);
+# endif // DIP_SWITCH_MAP_KEY_DELAY > 0
+
+ action_exec(on ? MAKE_DIPSWITCH_ON_EVENT(index, false) : MAKE_DIPSWITCH_OFF_EVENT(index, false));
+# if DIP_SWITCH_MAP_KEY_DELAY > 0
+ wait_ms(DIP_SWITCH_MAP_KEY_DELAY);
+# endif // DIP_SWITCH_MAP_KEY_DELAY > 0
+}
+#endif // DIP_SWITCH_MAP_ENABLE
+
void dip_switch_init(void) {
#ifdef DIP_SWITCH_PINS
# if defined(SPLIT_KEYBOARD) && defined(DIP_SWITCH_PINS_RIGHT)
if (!isLeftHand) {
const pin_t dip_switch_pad_right[] = DIP_SWITCH_PINS_RIGHT;
- for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
+ for (uint8_t i = 0; i < NUM_DIP_SWITCHES; i++) {
dip_switch_pad[i] = dip_switch_pad_right[i];
}
}
# endif
- for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
+ for (uint8_t i = 0; i < NUM_DIP_SWITCHES; i++) {
setPinInputHigh(dip_switch_pad[i]);
}
dip_switch_read(true);
@@ -108,7 +121,7 @@ void dip_switch_read(bool forced) {
}
#endif
- for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) {
+ for (uint8_t i = 0; i < NUM_DIP_SWITCHES; i++) {
#ifdef DIP_SWITCH_PINS
dip_switch_state[i] = !readPin(dip_switch_pad[i]);
#endif
@@ -118,11 +131,21 @@ void dip_switch_read(bool forced) {
dip_switch_mask |= dip_switch_state[i] << i;
if (last_dip_switch_state[i] != dip_switch_state[i] || forced) {
has_dip_state_changed = true;
+#ifndef DIP_SWITCH_MAP_ENABLE
dip_switch_update_kb(i, dip_switch_state[i]);
+#else
+ dip_switch_exec_mapping(i, dip_switch_state[i]);
+#endif
}
}
if (has_dip_state_changed) {
+#ifndef DIP_SWITCH_MAP_ENABLE
dip_switch_update_mask_kb(dip_switch_mask);
+#endif
memcpy(last_dip_switch_state, dip_switch_state, sizeof(dip_switch_state));
}
}
+
+void dip_switch_task(void) {
+ dip_switch_read(false);
+}
diff --git a/quantum/dip_switch.h b/quantum/dip_switch.h
index 6e79dcb0bf..7629859359 100644
--- a/quantum/dip_switch.h
+++ b/quantum/dip_switch.h
@@ -20,11 +20,36 @@
#include <stdbool.h>
#include <stdint.h>
+#include "gpio.h"
+#include "util.h"
+
+#if defined(DIP_SWITCH_PINS)
+# define NUM_DIP_SWITCHES ARRAY_SIZE(((pin_t[])DIP_SWITCH_PINS))
+#elif defined(DIP_SWITCH_MATRIX_GRID)
+typedef struct matrix_intersection_t {
+ uint8_t row;
+ uint8_t col;
+} matrix_intersection_t;
+# define NUM_DIP_SWITCHES ARRAY_SIZE(((matrix_intersection_t[])DIP_SWITCH_MATRIX_GRID))
+#endif
+
+#ifndef NUM_DIP_SWITCHES
+# define NUM_DIP_SWITCHES 0
+#endif
bool dip_switch_update_kb(uint8_t index, bool active);
bool dip_switch_update_user(uint8_t index, bool active);
bool dip_switch_update_mask_user(uint32_t state);
bool dip_switch_update_mask_kb(uint32_t state);
-void dip_switch_init(void);
void dip_switch_read(bool forced);
+
+void dip_switch_init(void);
+void dip_switch_task(void);
+
+#ifdef DIP_SWITCH_MAP_ENABLE
+# define NUM_DIP_STATES 2
+# define DIP_SWITCH_OFF_ON(off, on) \
+ { (off), (on) }
+extern const uint16_t dip_switch_map[NUM_DIP_SWITCHES][NUM_DIP_STATES];
+#endif // DIP_SWITCH_MAP_ENABLE
diff --git a/quantum/keyboard.c b/quantum/keyboard.c
index 86a1a9fea3..b5fa1a6e2e 100644
--- a/quantum/keyboard.c
+++ b/quantum/keyboard.c
@@ -615,7 +615,7 @@ void quantum_task(void) {
#endif
#ifdef DIP_SWITCH_ENABLE
- dip_switch_read(false);
+ dip_switch_task();
#endif
#ifdef AUTO_SHIFT_ENABLE
diff --git a/quantum/keyboard.h b/quantum/keyboard.h
index 5ea57815a7..0f39fde682 100644
--- a/quantum/keyboard.h
+++ b/quantum/keyboard.h
@@ -32,7 +32,7 @@ typedef struct {
uint8_t row;
} keypos_t;
-typedef enum keyevent_type_t { TICK_EVENT = 0, KEY_EVENT = 1, ENCODER_CW_EVENT = 2, ENCODER_CCW_EVENT = 3, COMBO_EVENT = 4 } keyevent_type_t;
+typedef enum keyevent_type_t { TICK_EVENT = 0, KEY_EVENT = 1, ENCODER_CW_EVENT = 2, ENCODER_CCW_EVENT = 3, COMBO_EVENT = 4, DIP_SWITCH_ON_EVENT = 5, DIP_SWITCH_OFF_EVENT = 6 } keyevent_type_t;
/* key event */
typedef struct {
@@ -48,6 +48,8 @@ typedef struct {
/* special keypos_t entries */
#define KEYLOC_ENCODER_CW 253
#define KEYLOC_ENCODER_CCW 252
+#define KEYLOC_DIP_SWITCH_ON 251
+#define KEYLOC_DIP_SWITCH_OFF 250
static inline bool IS_NOEVENT(const keyevent_t event) {
return event.type == TICK_EVENT;
@@ -64,6 +66,9 @@ static inline bool IS_COMBOEVENT(const keyevent_t event) {
static inline bool IS_ENCODEREVENT(const keyevent_t event) {
return event.type == ENCODER_CW_EVENT || event.type == ENCODER_CCW_EVENT;
}
+static inline bool IS_DIPSWITCHEVENT(const keyevent_t event) {
+ return event.type == DIP_SWITCH_ON_EVENT || event.type == DIP_SWITCH_OFF_EVENT;
+}
/* Common keypos_t object factory */
#define MAKE_KEYPOS(row_num, col_num) ((keypos_t){.row = (row_num), .col = (col_num)})
@@ -92,6 +97,12 @@ static inline bool IS_ENCODEREVENT(const keyevent_t event) {
# define MAKE_ENCODER_CCW_EVENT(enc_id, press) MAKE_EVENT(KEYLOC_ENCODER_CCW, (enc_id), (press), ENCODER_CCW_EVENT)
#endif // ENCODER_MAP_ENABLE
+#ifdef DIP_SWITCH_MAP_ENABLE
+/* Dip Switch events */
+# define MAKE_DIPSWITCH_ON_EVENT(switch_id, press) MAKE_EVENT(KEYLOC_DIP_SWITCH_ON, (switch_id), (press), DIP_SWITCH_ON_EVENT)
+# define MAKE_DIPSWITCH_OFF_EVENT(switch_id, press) MAKE_EVENT(KEYLOC_DIP_SWITCH_OFF, (switch_id), (press), DIP_SWITCH_OFF_EVENT)
+#endif // DIP_SWITCH_MAP_ENABLE
+
/* it runs once at early stage of startup before keyboard_init. */
void keyboard_setup(void);
/* it runs once after initializing host side protocol, debug and MCU peripherals. */
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 91e47a72ee..abdcd5c7ba 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -29,6 +29,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "encoder.h"
#endif
+#ifdef DIP_SWITCH_MAP_ENABLE
+# include "dip_switch.h"
+#endif
+
#ifdef BACKLIGHT_ENABLE
# include "backlight.h"
#endif
@@ -204,5 +208,13 @@ __attribute__((weak)) uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key
return keycode_at_encodermap_location(layer, key.col, false);
}
#endif // ENCODER_MAP_ENABLE
+#ifdef DIP_SWITCH_MAP_ENABLE
+ else if (key.row == KEYLOC_DIP_SWITCH_ON && key.col < NUM_DIP_SWITCHES) {
+ return keycode_at_dip_switch_map_location(key.col, true);
+ } else if (key.row == KEYLOC_DIP_SWITCH_OFF && key.col < NUM_DIP_SWITCHES) {
+ return keycode_at_dip_switch_map_location(key.col, false);
+ }
+#endif // DIP_SWITCH_MAP_ENABLE
+
return KC_NO;
}
diff --git a/quantum/keymap_extras/keymap_spanish_latin_america.h b/quantum/keymap_extras/keymap_spanish_latin_america.h
new file mode 100644
index 0000000000..92921811b3
--- /dev/null
+++ b/quantum/keymap_extras/keymap_spanish_latin_america.h
@@ -0,0 +1,105 @@
+// Copyright 2023 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*******************************************************************************
+ 88888888888 888 d8b .d888 d8b 888 d8b
+ 888 888 Y8P d88P" Y8P 888 Y8P
+ 888 888 888 888
+ 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
+ 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
+ 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
+ 888 888 888 888 X88 888 888 888 Y8b. 888 X88
+ 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
+ 888 888
+ 888 888
+ 888 888
+ .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
+ d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
+ 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
+ Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
+ "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
+ 888
+ Y8b d88P
+ "Y88P"
+*******************************************************************************/
+
+#pragma once
+#include "keycodes.h"
+// clang-format off
+
+// Aliases
+#define ES_PIPE KC_GRV // |
+#define ES_1 KC_1 // 1
+#define ES_2 KC_2 // 2
+#define ES_3 KC_3 // 3
+#define ES_4 KC_4 // 4
+#define ES_5 KC_5 // 5
+#define ES_6 KC_6 // 6
+#define ES_7 KC_7 // 7
+#define ES_8 KC_8 // 8
+#define ES_9 KC_9 // 9
+#define ES_0 KC_0 // 0
+#define ES_QUOT KC_MINS // '
+#define ES_IQUE KC_EQL // ¿
+#define ES_Q KC_Q // Q
+#define ES_W KC_W // W
+#define ES_E KC_E // E
+#define ES_R KC_R // R
+#define ES_T KC_T // T
+#define ES_Y KC_Y // Y
+#define ES_U KC_U // U
+#define ES_I KC_I // I
+#define ES_O KC_O // O
+#define ES_P KC_P // P
+#define ES_ACUT KC_LBRC // ´ (dead)
+#define ES_PLUS KC_RBRC // +
+#define ES_A KC_A // A
+#define ES_S KC_S // S
+#define ES_D KC_D // D
+#define ES_F KC_F // F
+#define ES_G KC_G // G
+#define ES_H KC_H // H
+#define ES_J KC_J // J
+#define ES_K KC_K // K
+#define ES_L KC_L // L
+#define ES_NTIL KC_SCLN // Ñ
+#define ES_LCBR KC_QUOT // {
+#define ES_RCBR KC_NUHS // }
+#define ES_LABK KC_NUBS // <
+#define ES_Z KC_Z // Z
+#define ES_X KC_X // X
+#define ES_C KC_C // C
+#define ES_V KC_V // V
+#define ES_B KC_B // B
+#define ES_N KC_N // N
+#define ES_M KC_M // M
+#define ES_COMM KC_COMM // ,
+#define ES_DOT KC_DOT // .
+#define ES_MINS KC_SLSH // -
+#define ES_MORD S(ES_PIPE) // °
+#define ES_EXLM S(ES_1) // !
+#define ES_DQUO S(ES_2) // "
+#define ES_NUMB S(ES_3) // #
+#define ES_DLR S(ES_4) // $
+#define ES_PERC S(ES_5) // %
+#define ES_AMPR S(ES_6) // &
+#define ES_SLSH S(ES_7) // /
+#define ES_LPRN S(ES_8) // (
+#define ES_RPRN S(ES_9) // )
+#define ES_EQL S(ES_0) // =
+#define ES_QUES S(ES_QUOT) // ?
+#define ES_IEXL S(ES_IQUE) // ¡
+#define ES_DIAE S(ES_ACUT) // ¨ (dead)
+#define ES_ASTR S(ES_PLUS) // *
+#define ES_LBRC S(ES_LCBR) // [
+#define ES_RBRC S(ES_RCBR) // ]
+#define ES_RABK S(ES_LABK) // >
+#define ES_SCLN S(ES_COMM) // ;
+#define ES_COLN S(ES_DOT) // :
+#define ES_UNDS S(ES_MINS) // _
+#define ES_NOT ALGR(ES_PIPE) // ¬
+#define ES_BSLS ALGR(ES_QUOT) // (backslash)
+#define ES_AT ALGR(ES_Q) // @
+#define ES_TILD ALGR(ES_PLUS) // ~
+#define ES_CIRC ALGR(ES_LCBR) // ^
+
diff --git a/quantum/keymap_extras/sendstring_spanish_latin_america.h b/quantum/keymap_extras/sendstring_spanish_latin_america.h
new file mode 100644
index 0000000000..3bfdf7d5cb
--- /dev/null
+++ b/quantum/keymap_extras/sendstring_spanish_latin_america.h
@@ -0,0 +1,120 @@
+/* Copyright 2023 Juan David Díaz
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// Sendstring lookup tables for Latam Spanish layouts
+
+#pragma once
+
+#include "send_string.h"
+#include "keymap_spanish_latin_america.h"
+
+// clang-format off
+
+const uint8_t ascii_to_shift_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 0),
+ KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1),
+ KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 0),
+ KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1),
+ KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1),
+ KCLUT_ENTRY(1, 1, 1, 1, 0, 1, 0, 1),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
+};
+
+const uint8_t ascii_to_altgr_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 1, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0)
+};
+
+const uint8_t ascii_to_dead_lut[16] PROGMEM = {
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0),
+ KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0),
+ KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0)
+};
+
+const uint8_t ascii_to_keycode_lut[128] PROGMEM = {
+ // NUL SOH STX ETX EOT ENQ ACK BEL
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // BS TAB LF VT FF CR SO SI
+ KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ // CAN EM SUB ESC FS GS RS US
+ XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+
+ // ! " # $ % & '
+ KC_SPC, ES_1, ES_2, ES_3, ES_4, ES_5, ES_6, ES_QUOT,
+ // ( ) * + , - . /
+ ES_8, ES_9, ES_PLUS, ES_PLUS, ES_COMM, ES_MINS, ES_DOT, ES_7,
+ // 0 1 2 3 4 5 6 7
+ ES_0, ES_1, ES_2, ES_3, ES_4, ES_5, ES_6, ES_7,
+ // 8 9 : ; < = > ?
+ ES_8, ES_9, ES_DOT, ES_COMM, ES_LABK, ES_0, ES_LABK, ES_QUOT,
+ // @ A B C D E F G
+ ES_Q, ES_A, ES_B, ES_C, ES_D, ES_E, ES_F, ES_G,
+ // H I J K L M N O
+ ES_H, ES_I, ES_J, ES_K, ES_L, ES_M, ES_N, ES_O,
+ // P Q R S T U V W
+ ES_P, ES_Q, ES_R, ES_S, ES_T, ES_U, ES_V, ES_W,
+ // X Y Z [ \ ] ^ _
+ ES_X, ES_Y, ES_Z, ES_LCBR, ES_QUOT, ES_RCBR, ES_LCBR, ES_MINS,
+ // ` a b c d e f g
+ ES_RCBR, ES_A, ES_B, ES_C, ES_D, ES_E, ES_F, ES_G,
+ // h i j k l m n o
+ ES_H, ES_I, ES_J, ES_K, ES_L, ES_M, ES_N, ES_O,
+ // p q r s t u v w
+ ES_P, ES_Q, ES_R, ES_S, ES_T, ES_U, ES_V, ES_W,
+ // x y z { | } ~ DEL
+ ES_X, ES_Y, ES_Z, ES_LCBR, ES_PIPE, ES_RCBR, ES_PLUS, KC_DEL
+};
diff --git a/quantum/keymap_introspection.c b/quantum/keymap_introspection.c
index e4a01d2e9a..71e3b429ea 100644
--- a/quantum/keymap_introspection.c
+++ b/quantum/keymap_introspection.c
@@ -72,6 +72,24 @@ __attribute__((weak)) uint16_t keycode_at_encodermap_location(uint8_t layer_num,
#endif // defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Dip Switch mapping
+
+#if defined(DIP_SWITCH_ENABLE) && defined(DIP_SWITCH_MAP_ENABLE)
+
+uint16_t keycode_at_dip_switch_map_location_raw(uint8_t switch_idx, bool on) {
+ if (switch_idx < NUM_DIP_SWITCHES) {
+ return pgm_read_word(&dip_switch_map[switch_idx][!!on]);
+ }
+ return KC_TRNS;
+}
+
+uint16_t keycode_at_dip_switch_map_location(uint8_t switch_idx, bool on) {
+ return keycode_at_dip_switch_map_location_raw(switch_idx, on);
+}
+
+#endif // defined(DIP_SWITCH_ENABLE) && defined(DIP_SWITCH_MAP_ENABLE)
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Combos
#if defined(COMBO_ENABLE)
diff --git a/quantum/keymap_introspection.h b/quantum/keymap_introspection.h
index 2012a2b8cc..f7516bf42a 100644
--- a/quantum/keymap_introspection.h
+++ b/quantum/keymap_introspection.h
@@ -36,6 +36,18 @@ uint16_t keycode_at_encodermap_location(uint8_t layer_num, uint8_t encoder_idx,
#endif // defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Dip Switch mapping
+
+#if defined(DIP_SWITCH_ENABLE) && defined(DIP_SWITCH_MAP_ENABLE)
+
+// Get the keycode for the dip_switch mapping location, stored in firmware rather than any other persistent storage
+uint16_t keycode_at_dip_switch_map_location_raw(uint8_t switch_idx, bool on);
+// Get the keycode for the dip_switch mapping location, potentially stored dynamically
+uint16_t keycode_at_dip_switch_map_location(uint8_t switch_idx, bool on);
+
+#endif // defined(DIP_SWITCH_ENABLE) && defined(DIP_SWITCH_MAP_ENABLE)
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Combos
#if defined(COMBO_ENABLE)
diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c
index 4d67a295df..4699c4a4c2 100644
--- a/quantum/led_matrix/led_matrix.c
+++ b/quantum/led_matrix/led_matrix.c
@@ -74,9 +74,6 @@ static uint8_t led_last_enable = UINT8_MAX;
static uint8_t led_last_effect = UINT8_MAX;
static effect_params_t led_effect_params = {0, LED_FLAG_ALL, false};
static led_task_states led_task_state = SYNCING;
-#if LED_MATRIX_TIMEOUT > 0
-static uint32_t led_anykey_timer;
-#endif // LED_MATRIX_TIMEOUT > 0
// double buffers
static uint32_t led_timer_buffer;
@@ -156,9 +153,6 @@ void process_led_matrix(uint8_t row, uint8_t col, bool pressed) {
#ifndef LED_MATRIX_SPLIT
if (!is_keyboard_master()) return;
#endif
-#if LED_MATRIX_TIMEOUT > 0
- led_anykey_timer = 0;
-#endif // LED_MATRIX_TIMEOUT > 0
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
uint8_t led[LED_HITS_TO_REMEMBER];
@@ -208,22 +202,11 @@ static bool led_matrix_none(effect_params_t *params) {
}
static void led_task_timers(void) {
-#if defined(LED_MATRIX_KEYREACTIVE_ENABLED) || LED_MATRIX_TIMEOUT > 0
+#if defined(LED_MATRIX_KEYREACTIVE_ENABLED)
uint32_t deltaTime = sync_timer_elapsed32(led_timer_buffer);
-#endif // defined(LED_MATRIX_KEYREACTIVE_ENABLED) || LED_MATRIX_TIMEOUT > 0
+#endif // defined(LED_MATRIX_KEYREACTIVE_ENABLED)
led_timer_buffer = sync_timer_read32();
- // Update double buffer timers
-#if LED_MATRIX_TIMEOUT > 0
- if (led_anykey_timer < UINT32_MAX) {
- if (UINT32_MAX - deltaTime < led_anykey_timer) {
- led_anykey_timer = UINT32_MAX;
- } else {
- led_anykey_timer += deltaTime;
- }
- }
-#endif // LED_MATRIX_TIMEOUT > 0
-
// Update double buffer last hit timers
#ifdef LED_MATRIX_KEYREACTIVE_ENABLED
uint8_t count = last_hit_buffer.count;
@@ -329,7 +312,7 @@ void led_matrix_task(void) {
// while suspended and just do a software shutdown. This is a cheap hack for now.
bool suspend_backlight = suspend_state ||
#if LED_MATRIX_TIMEOUT > 0
- (led_anykey_timer > (uint32_t)LED_MATRIX_TIMEOUT) ||
+ (last_input_activity_elapsed() > (uint32_t)LED_MATRIX_TIMEOUT) ||
#endif // LED_MATRIX_TIMEOUT > 0
false;
diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h
index c903a230f4..153abf2975 100644
--- a/quantum/led_matrix/led_matrix.h
+++ b/quantum/led_matrix/led_matrix.h
@@ -23,32 +23,9 @@
#include <stdint.h>
#include <stdbool.h>
#include "led_matrix_types.h"
+#include "led_matrix_drivers.h"
#include "keyboard.h"
-#if defined(LED_MATRIX_IS31FL3218)
-# include "is31fl3218-simple.h"
-#elif defined(LED_MATRIX_IS31FL3731)
-# include "is31fl3731-simple.h"
-#endif
-#ifdef LED_MATRIX_IS31FL3733
-# include "is31fl3733-simple.h"
-#endif
-#ifdef LED_MATRIX_IS31FL3736
-# include "is31fl3736-simple.h"
-#endif
-#ifdef LED_MATRIX_IS31FL3737
-# include "is31fl3737-simple.h"
-#endif
-#ifdef LED_MATRIX_IS31FL3741
-# include "is31fl3741-simple.h"
-#endif
-#if defined(IS31FLCOMMON)
-# include "is31flcommon.h"
-#endif
-#ifdef LED_MATRIX_SNLED27351
-# include "snled27351-simple.h"
-#endif
-
#ifndef LED_MATRIX_TIMEOUT
# define LED_MATRIX_TIMEOUT 0
#endif
@@ -193,18 +170,6 @@ led_flags_t led_matrix_get_flags(void);
void led_matrix_set_flags(led_flags_t flags);
void led_matrix_set_flags_noeeprom(led_flags_t flags);
-typedef struct {
- /* Perform any initialisation required for the other driver functions to work. */
- void (*init)(void);
-
- /* Set the brightness of a single LED in the buffer. */
- void (*set_value)(int index, uint8_t value);
- /* Set the brightness of all LEDS on the keyboard in the buffer. */
- void (*set_value_all)(uint8_t value);
- /* Flush any buffered changes to the hardware. */
- void (*flush)(void);
-} led_matrix_driver_t;
-
static inline bool led_matrix_check_finished_leds(uint8_t led_idx) {
#if defined(LED_MATRIX_SPLIT)
if (is_keyboard_left()) {
@@ -217,8 +182,6 @@ static inline bool led_matrix_check_finished_leds(uint8_t led_idx) {
#endif
}
-extern const led_matrix_driver_t led_matrix_driver;
-
extern led_eeconfig_t led_matrix_eeconfig;
extern uint32_t g_led_timer;
diff --git a/quantum/led_matrix/led_matrix_drivers.c b/quantum/led_matrix/led_matrix_drivers.c
index 117bed9851..672238a260 100644
--- a/quantum/led_matrix/led_matrix_drivers.c
+++ b/quantum/led_matrix/led_matrix_drivers.c
@@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "led_matrix.h"
+#include "led_matrix_drivers.h"
/* Each driver needs to define a struct:
*
diff --git a/quantum/led_matrix/led_matrix_drivers.h b/quantum/led_matrix/led_matrix_drivers.h
new file mode 100644
index 0000000000..b0ef3dfafc
--- /dev/null
+++ b/quantum/led_matrix/led_matrix_drivers.h
@@ -0,0 +1,38 @@
+// Copyright 2023 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <stdint.h>
+
+#if defined(LED_MATRIX_IS31FL3218)
+# include "is31fl3218-simple.h"
+#elif defined(LED_MATRIX_IS31FL3731)
+# include "is31fl3731-simple.h"
+#elif defined(LED_MATRIX_IS31FL3733)
+# include "is31fl3733-simple.h"
+#elif defined(LED_MATRIX_IS31FL3736)
+# include "is31fl3736-simple.h"
+#elif defined(LED_MATRIX_IS31FL3737)
+# include "is31fl3737-simple.h"
+#elif defined(LED_MATRIX_IS31FL3741)
+# include "is31fl3741-simple.h"
+#elif defined(IS31FLCOMMON)
+# include "is31flcommon.h"
+#elif defined(LED_MATRIX_SNLED27351)
+# include "snled27351-simple.h"
+#endif
+
+typedef struct {
+ /* Perform any initialisation required for the other driver functions to work. */
+ void (*init)(void);
+
+ /* Set the brightness of a single LED in the buffer. */
+ void (*set_value)(int index, uint8_t value);
+ /* Set the brightness of all LEDS on the keyboard in the buffer. */
+ void (*set_value_all)(uint8_t value);
+ /* Flush any buffered changes to the hardware. */
+ void (*flush)(void);
+} led_matrix_driver_t;
+
+extern const led_matrix_driver_t led_matrix_driver;
diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c
index d93d189827..ebaf3077dc 100644
--- a/quantum/rgb_matrix/rgb_matrix.c
+++ b/quantum/rgb_matrix/rgb_matrix.c
@@ -76,9 +76,6 @@ static uint8_t rgb_last_enable = UINT8_MAX;
static uint8_t rgb_last_effect = UINT8_MAX;
static effect_params_t rgb_effect_params = {0, LED_FLAG_ALL, false};
static rgb_task_states rgb_task_state = SYNCING;
-#if RGB_MATRIX_TIMEOUT > 0
-static uint32_t rgb_anykey_timer;
-#endif // RGB_MATRIX_TIMEOUT > 0
// double buffers
static uint32_t rgb_timer_buffer;
@@ -163,9 +160,6 @@ void process_rgb_matrix(uint8_t row, uint8_t col, bool pressed) {
#ifndef RGB_MATRIX_SPLIT
if (!is_keyboard_master()) return;
#endif
-#if RGB_MATRIX_TIMEOUT > 0
- rgb_anykey_timer = 0;
-#endif // RGB_MATRIX_TIMEOUT > 0
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
uint8_t led[LED_HITS_TO_REMEMBER];
@@ -246,18 +240,11 @@ static bool rgb_matrix_none(effect_params_t *params) {
}
static void rgb_task_timers(void) {
-#if defined(RGB_MATRIX_KEYREACTIVE_ENABLED) || RGB_MATRIX_TIMEOUT > 0
+#if defined(RGB_MATRIX_KEYREACTIVE_ENABLED)
uint32_t deltaTime = sync_timer_elapsed32(rgb_timer_buffer);
-#endif // defined(RGB_MATRIX_KEYREACTIVE_ENABLED) || RGB_MATRIX_TIMEOUT > 0
+#endif // defined(RGB_MATRIX_KEYREACTIVE_ENABLED)
rgb_timer_buffer = sync_timer_read32();
- // Update double buffer timers
-#if RGB_MATRIX_TIMEOUT > 0
- if (rgb_anykey_timer + deltaTime <= UINT32_MAX) {
- rgb_anykey_timer += deltaTime;
- }
-#endif // RGB_MATRIX_TIMEOUT > 0
-
// Update double buffer last hit timers
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
uint8_t count = last_hit_buffer.count;
@@ -370,7 +357,7 @@ void rgb_matrix_task(void) {
// while suspended and just do a software shutdown. This is a cheap hack for now.
bool suspend_backlight = suspend_state ||
#if RGB_MATRIX_TIMEOUT > 0
- (rgb_anykey_timer > (uint32_t)RGB_MATRIX_TIMEOUT) ||
+ (last_input_activity_elapsed() > (uint32_t)RGB_MATRIX_TIMEOUT) ||
#endif // RGB_MATRIX_TIMEOUT > 0
false;
diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h
index 9a3ffb8ea3..b1bf839bf6 100644
--- a/quantum/rgb_matrix/rgb_matrix.h
+++ b/quantum/rgb_matrix/rgb_matrix.h
@@ -21,31 +21,10 @@
#include <stdint.h>
#include <stdbool.h>
#include "rgb_matrix_types.h"
+#include "rgb_matrix_drivers.h"
#include "color.h"
#include "keyboard.h"
-#if defined(RGB_MATRIX_IS31FL3218)
-# include "is31fl3218.h"
-#elif defined(RGB_MATRIX_IS31FL3731)
-# include "is31fl3731.h"
-#elif defined(RGB_MATRIX_IS31FL3733)
-# include "is31fl3733.h"
-#elif defined(RGB_MATRIX_IS31FL3736)
-# include "is31fl3736.h"
-#elif defined(RGB_MATRIX_IS31FL3737)
-# include "is31fl3737.h"
-#elif defined(RGB_MATRIX_IS31FL3741)
-# include "is31fl3741.h"
-#elif defined(IS31FLCOMMON)
-# include "is31flcommon.h"
-#elif defined(RGB_MATRIX_SNLED27351)
-# include "snled27351.h"
-#elif defined(RGB_MATRIX_AW20216S)
-# include "aw20216s.h"
-#elif defined(RGB_MATRIX_WS2812)
-# include "ws2812.h"
-#endif
-
#ifndef RGB_MATRIX_TIMEOUT
# define RGB_MATRIX_TIMEOUT 0
#endif
@@ -272,17 +251,6 @@ void rgb_matrix_set_flags_noeeprom(led_flags_t flags);
# define rgblight_decrease_speed_noeeprom rgb_matrix_decrease_speed_noeeprom
#endif
-typedef struct {
- /* Perform any initialisation required for the other driver functions to work. */
- void (*init)(void);
- /* Set the colour of a single LED in the buffer. */
- void (*set_color)(int index, uint8_t r, uint8_t g, uint8_t b);
- /* Set the colour of all LEDS on the keyboard in the buffer. */
- void (*set_color_all)(uint8_t r, uint8_t g, uint8_t b);
- /* Flush any buffered changes to the hardware. */
- void (*flush)(void);
-} rgb_matrix_driver_t;
-
static inline bool rgb_matrix_check_finished_leds(uint8_t led_idx) {
#if defined(RGB_MATRIX_SPLIT)
if (is_keyboard_left()) {
@@ -295,8 +263,6 @@ static inline bool rgb_matrix_check_finished_leds(uint8_t led_idx) {
#endif
}
-extern const rgb_matrix_driver_t rgb_matrix_driver;
-
extern rgb_config_t rgb_matrix_config;
extern uint32_t g_rgb_timer;
diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c
index 0f979cb233..e7bed0bf72 100644
--- a/quantum/rgb_matrix/rgb_matrix_drivers.c
+++ b/quantum/rgb_matrix/rgb_matrix_drivers.c
@@ -14,7 +14,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "rgb_matrix.h"
+#include "rgb_matrix_drivers.h"
+
+#include <stdbool.h>
+#include "keyboard.h"
+#include "color.h"
#include "util.h"
/* Each driver needs to define the struct
diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.h b/quantum/rgb_matrix/rgb_matrix_drivers.h
new file mode 100644
index 0000000000..991344f087
--- /dev/null
+++ b/quantum/rgb_matrix/rgb_matrix_drivers.h
@@ -0,0 +1,41 @@
+// Copyright 2023 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <stdint.h>
+
+#if defined(RGB_MATRIX_AW20216S)
+# include "aw20216s.h"
+#elif defined(RGB_MATRIX_IS31FL3218)
+# include "is31fl3218.h"
+#elif defined(RGB_MATRIX_IS31FL3731)
+# include "is31fl3731.h"
+#elif defined(RGB_MATRIX_IS31FL3733)
+# include "is31fl3733.h"
+#elif defined(RGB_MATRIX_IS31FL3736)
+# include "is31fl3736.h"
+#elif defined(RGB_MATRIX_IS31FL3737)
+# include "is31fl3737.h"
+#elif defined(RGB_MATRIX_IS31FL3741)
+# include "is31fl3741.h"
+#elif defined(IS31FLCOMMON)
+# include "is31flcommon.h"
+#elif defined(RGB_MATRIX_SNLED27351)
+# include "snled27351.h"
+#elif defined(RGB_MATRIX_WS2812)
+# include "ws2812.h"
+#endif
+
+typedef struct {
+ /* Perform any initialisation required for the other driver functions to work. */
+ void (*init)(void);
+ /* Set the colour of a single LED in the buffer. */
+ void (*set_color)(int index, uint8_t r, uint8_t g, uint8_t b);
+ /* Set the colour of all LEDS on the keyboard in the buffer. */
+ void (*set_color_all)(uint8_t r, uint8_t g, uint8_t b);
+ /* Flush any buffered changes to the hardware. */
+ void (*flush)(void);
+} rgb_matrix_driver_t;
+
+extern const rgb_matrix_driver_t rgb_matrix_driver;
diff --git a/quantum/rgblight/rgblight.c b/quantum/rgblight/rgblight.c
index 8ac886d441..8a5240568c 100644
--- a/quantum/rgblight/rgblight.c
+++ b/quantum/rgblight/rgblight.c
@@ -900,12 +900,6 @@ void rgblight_wakeup(void) {
#endif
-__attribute__((weak)) void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds) {
- ws2812_setleds(start_led, num_leds);
-}
-
-#ifndef RGBLIGHT_CUSTOM
-
void rgblight_set(void) {
rgb_led_t *start_led;
uint8_t num_leds = rgblight_ranges.clipping_num_leds;
@@ -915,42 +909,41 @@ void rgblight_set(void) {
led[i].r = 0;
led[i].g = 0;
led[i].b = 0;
-# ifdef RGBW
+#ifdef RGBW
led[i].w = 0;
-# endif
+#endif
}
}
-# ifdef RGBLIGHT_LAYERS
+#ifdef RGBLIGHT_LAYERS
if (rgblight_layers != NULL
-# if !defined(RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF)
+# if !defined(RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF)
&& rgblight_config.enable
-# elif defined(RGBLIGHT_SLEEP)
+# elif defined(RGBLIGHT_SLEEP)
&& !is_suspended
-# endif
+# endif
) {
rgblight_layers_write();
}
-# endif
+#endif
-# ifdef RGBLIGHT_LED_MAP
+#ifdef RGBLIGHT_LED_MAP
rgb_led_t led0[RGBLED_NUM];
for (uint8_t i = 0; i < RGBLED_NUM; i++) {
led0[i] = led[pgm_read_byte(&led_map[i])];
}
start_led = led0 + rgblight_ranges.clipping_start_pos;
-# else
+#else
start_led = led + rgblight_ranges.clipping_start_pos;
-# endif
+#endif
-# ifdef RGBW
+#ifdef RGBW
for (uint8_t i = 0; i < num_leds; i++) {
convert_rgb_to_rgbw(&start_led[i]);
}
-# endif
- rgblight_call_driver(start_led, num_leds);
-}
#endif
+ rgblight_driver.setleds(start_led, num_leds);
+}
#ifdef RGBLIGHT_SPLIT
/* for split keyboard master side */
diff --git a/quantum/rgblight/rgblight.h b/quantum/rgblight/rgblight.h
index a222ab6b9f..d2b8a24b1e 100644
--- a/quantum/rgblight/rgblight.h
+++ b/quantum/rgblight/rgblight.h
@@ -160,6 +160,7 @@ enum RGBLIGHT_EFFECT_MODE {
#include <stdint.h>
#include <stdbool.h>
+#include "rgblight_drivers.h"
#include "progmem.h"
#include "eeconfig.h"
#include "ws2812.h"
diff --git a/quantum/rgblight/rgblight_drivers.c b/quantum/rgblight/rgblight_drivers.c
new file mode 100644
index 0000000000..45b60e1a5f
--- /dev/null
+++ b/quantum/rgblight/rgblight_drivers.c
@@ -0,0 +1,20 @@
+// Copyright 2023 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "rgblight_drivers.h"
+
+#if defined(RGBLIGHT_WS2812)
+# include "ws2812.h"
+
+const rgblight_driver_t rgblight_driver = {
+ .setleds = ws2812_setleds,
+};
+
+#elif defined(RGBLIGHT_APA102)
+# include "apa102.h"
+
+const rgblight_driver_t rgblight_driver = {
+ .setleds = apa102_setleds,
+};
+
+#endif
diff --git a/quantum/rgblight/rgblight_drivers.h b/quantum/rgblight/rgblight_drivers.h
new file mode 100644
index 0000000000..f7125a6f3d
--- /dev/null
+++ b/quantum/rgblight/rgblight_drivers.h
@@ -0,0 +1,13 @@
+// Copyright 2023 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <stdint.h>
+#include "color.h"
+
+typedef struct {
+ void (*setleds)(rgb_led_t *ledarray, uint16_t number_of_leds);
+} rgblight_driver_t;
+
+extern const rgblight_driver_t rgblight_driver;