aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common_features.mk9
-rw-r--r--drivers/led/ckled2001.c226
-rw-r--r--drivers/led/ckled2001.h339
-rw-r--r--quantum/rgb_matrix/rgb_matrix.h2
-rw-r--r--quantum/rgb_matrix/rgb_matrix_drivers.c49
5 files changed, 623 insertions, 2 deletions
diff --git a/common_features.mk b/common_features.mk
index 0d6b86b1e..b605dfbe5 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -232,7 +232,7 @@ endif
232endif 232endif
233 233
234RGB_MATRIX_ENABLE ?= no 234RGB_MATRIX_ENABLE ?= no
235VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 WS2812 custom 235VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 CKLED2001 WS2812 custom
236 236
237ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes) 237ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
238 ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),) 238 ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),)
@@ -288,6 +288,13 @@ endif
288 QUANTUM_LIB_SRC += i2c_master.c 288 QUANTUM_LIB_SRC += i2c_master.c
289 endif 289 endif
290 290
291 ifeq ($(strip $(RGB_MATRIX_DRIVER)), CKLED2001)
292 OPT_DEFS += -DCKLED2001 -DSTM32_I2C -DHAL_USE_I2C=TRUE
293 COMMON_VPATH += $(DRIVER_PATH)/led
294 SRC += ckled2001.c
295 QUANTUM_LIB_SRC += i2c_master.c
296 endif
297
291 ifeq ($(strip $(RGB_MATRIX_DRIVER)), WS2812) 298 ifeq ($(strip $(RGB_MATRIX_DRIVER)), WS2812)
292 OPT_DEFS += -DWS2812 299 OPT_DEFS += -DWS2812
293 WS2812_DRIVER_REQUIRED := yes 300 WS2812_DRIVER_REQUIRED := yes
diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c
new file mode 100644
index 000000000..630730343
--- /dev/null
+++ b/drivers/led/ckled2001.c
@@ -0,0 +1,226 @@
1/* Copyright 2021 @ Keychron (https://www.keychron.com)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "ckled2001.h"
18#include "i2c_master.h"
19#include "wait.h"
20
21#ifndef CKLED2001_TIMEOUT
22# define CKLED2001_TIMEOUT 100
23#endif
24
25#ifndef CKLED2001_PERSISTENCE
26# define CKLED2001_PERSISTENCE 0
27#endif
28
29#ifndef PHASE_CHANNEL
30# define PHASE_CHANNEL MSKPHASE_12CHANNEL
31#endif
32
33// Transfer buffer for TWITransmitData()
34uint8_t g_twi_transfer_buffer[20];
35
36// These buffers match the CKLED2001 PWM registers.
37// The control buffers match the PG0 LED On/Off registers.
38// Storing them like this is optimal for I2C transfers to the registers.
39// We could optimize this and take out the unused registers from these
40// buffers and the transfers in CKLED2001_write_pwm_buffer() but it's
41// probably not worth the extra complexity.
42uint8_t g_pwm_buffer[DRIVER_COUNT][192];
43bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false};
44
45uint8_t g_led_control_registers[DRIVER_COUNT][24] = {0};
46bool g_led_control_registers_update_required[DRIVER_COUNT] = {false};
47
48bool CKLED2001_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
49 // If the transaction fails function returns false.
50 g_twi_transfer_buffer[0] = reg;
51 g_twi_transfer_buffer[1] = data;
52
53#if CKLED2001_PERSISTENCE > 0
54 for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) {
55 if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) {
56 return false;
57 }
58 }
59#else
60 if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) {
61 return false;
62 }
63#endif
64 return true;
65}
66
67bool CKLED2001_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
68 // Assumes PG1 is already selected.
69 // If any of the transactions fails function returns false.
70 // Transmit PWM registers in 12 transfers of 16 bytes.
71 // g_twi_transfer_buffer[] is 20 bytes
72
73 // Iterate over the pwm_buffer contents at 16 byte intervals.
74 for (int i = 0; i < 192; i += 16) {
75 g_twi_transfer_buffer[0] = i;
76 // Copy the data from i to i+15.
77 // Device will auto-increment register for data after the first byte
78 // Thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer.
79 for (int j = 0; j < 16; j++) {
80 g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j];
81 }
82
83#if CKLED2001_PERSISTENCE > 0
84 for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) {
85 if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) {
86 return false;
87 }
88 }
89#else
90 if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) {
91 return false;
92 }
93#endif
94 }
95 return true;
96}
97
98void CKLED2001_init(uint8_t addr) {
99 // Select to function page
100 CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE);
101 // Setting LED driver to shutdown mode
102 CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE);
103 // Setting internal channel pulldown/pullup
104 CKLED2001_write_register(addr, PDU_REG, MSKSET_CA_CB_CHANNEL);
105 // Select number of scan phase
106 CKLED2001_write_register(addr, SCAN_PHASE_REG, PHASE_CHANNEL);
107 // Setting PWM Delay Phase
108 CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE1_REG, MSKPWM_DELAY_PHASE_ENABLE);
109 // Setting Driving/Sinking Channel Slew Rate
110 CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE2_REG, MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE);
111 // Setting Iref
112 CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_DISABLE);
113 // Set LED CONTROL PAGE (Page 0)
114 CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE);
115 for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) {
116 CKLED2001_write_register(addr, i, 0x00);
117 }
118
119 // Set PWM PAGE (Page 1)
120 CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE);
121 for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) {
122 CKLED2001_write_register(addr, i, 0x00);
123 }
124
125 // Set CURRENT PAGE (Page 4)
126 CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, CURRENT_TUNE_PAGE);
127 for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) {
128 CKLED2001_write_register(addr, i, 0xFF);
129 }
130
131 // Enable LEDs ON/OFF
132 CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE);
133 for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) {
134 CKLED2001_write_register(addr, i, 0xFF);
135 }
136
137 // Select to function page
138 CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE);
139 // Setting LED driver to normal mode
140 CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE);
141}
142
143void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
144 if (index >= 0 && index < DRIVER_LED_TOTAL) {
145 ckled2001_led led = g_ckled2001_leds[index];
146
147 g_pwm_buffer[led.driver][led.r] = red;
148 g_pwm_buffer[led.driver][led.g] = green;
149 g_pwm_buffer[led.driver][led.b] = blue;
150 g_pwm_buffer_update_required[led.driver] = true;
151 }
152}
153
154void CKLED2001_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
155 for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
156 CKLED2001_set_color(i, red, green, blue);
157 }
158}
159
160void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, bool blue) {
161 ckled2001_led led = g_ckled2001_leds[index];
162
163 uint8_t control_register_r = led.r / 8;
164 uint8_t control_register_g = led.g / 8;
165 uint8_t control_register_b = led.b / 8;
166 uint8_t bit_r = led.r % 8;
167 uint8_t bit_g = led.g % 8;
168 uint8_t bit_b = led.b % 8;
169
170 if (red) {
171 g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r);
172 } else {
173 g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r);
174 }
175 if (green) {
176 g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g);
177 } else {
178 g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g);
179 }
180 if (blue) {
181 g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b);
182 } else {
183 g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b);
184 }
185
186 g_led_control_registers_update_required[led.driver] = true;
187}
188
189void CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index) {
190 if (g_pwm_buffer_update_required[index]) {
191 CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE);
192
193 // If any of the transactions fail we risk writing dirty PG0,
194 // refresh page 0 just in case.
195 if (!CKLED2001_write_pwm_buffer(addr, g_pwm_buffer[index])) {
196 g_led_control_registers_update_required[index] = true;
197 }
198 }
199 g_pwm_buffer_update_required[index] = false;
200}
201
202void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) {
203 if (g_led_control_registers_update_required[index]) {
204 CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE);
205 for (int i = 0; i < 24; i++) {
206 CKLED2001_write_register(addr, i, g_led_control_registers[index][i]);
207 }
208 }
209 g_led_control_registers_update_required[index] = false;
210}
211
212void CKLED2001_return_normal(uint8_t addr) {
213 // Select to function page
214 CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE);
215 // Setting LED driver to normal mode
216 CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE);
217}
218
219void CKLED2001_shutdown(uint8_t addr) {
220 // Select to function page
221 CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE);
222 // Setting LED driver to shutdown mode
223 CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE);
224 // Write SW Sleep Register
225 CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_ENABLE);
226}
diff --git a/drivers/led/ckled2001.h b/drivers/led/ckled2001.h
new file mode 100644
index 000000000..efe399690
--- /dev/null
+++ b/drivers/led/ckled2001.h
@@ -0,0 +1,339 @@
1/* Copyright 2021 @ Keychron (https://www.keychron.com)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include <stdint.h>
20#include <stdbool.h>
21#include "progmem.h"
22
23typedef struct ckled2001_led {
24 uint8_t driver : 2;
25 uint8_t r;
26 uint8_t g;
27 uint8_t b;
28} __attribute__((packed)) ckled2001_led;
29
30extern const ckled2001_led __flash g_ckled2001_leds[DRIVER_LED_TOTAL];
31
32void CKLED2001_init(uint8_t addr);
33bool CKLED2001_write_register(uint8_t addr, uint8_t reg, uint8_t data);
34bool CKLED2001_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);
35
36void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
37void CKLED2001_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
38
39void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, bool blue);
40
41// This should not be called from an interrupt
42// (eg. from a timer interrupt).
43// Call this while idle (in between matrix scans).
44// If the buffer is dirty, it will update the driver with the buffer.
45void CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index);
46void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index);
47
48void CKLED2001_return_normal(uint8_t addr);
49void CKLED2001_shutdown(uint8_t addr);
50
51// Registers Page Define
52#define CONFIGURE_CMD_PAGE 0xFD
53#define LED_CONTROL_PAGE 0x00
54#define LED_PWM_PAGE 0x01
55#define FUNCTION_PAGE 0x03
56#define CURRENT_TUNE_PAGE 0x04
57
58// Function Register: address 0x00
59#define CONFIGURATION_REG 0x00
60#define MSKSW_SHUT_DOWN_MODE (0x0 << 0)
61#define MSKSW_NORMAL_MODE (0x1 << 0)
62
63#define DRIVER_ID_REG 0x11
64#define CKLED2001_ID 0x8A
65
66#define PDU_REG 0x13
67#define MSKSET_CA_CB_CHANNEL 0xAA
68#define MSKCLR_CA_CB_CHANNEL 0x00
69
70#define SCAN_PHASE_REG 0x14
71#define MSKPHASE_12CHANNEL 0x00
72#define MSKPHASE_11CHANNEL 0x01
73#define MSKPHASE_10CHANNEL 0x02
74#define MSKPHASE_9CHANNEL 0x03
75#define MSKPHASE_8CHANNEL 0x04
76#define MSKPHASE_7CHANNEL 0x05
77#define MSKPHASE_6CHANNEL 0x06
78#define MSKPHASE_5CHANNEL 0x07
79#define MSKPHASE_4CHANNEL 0x08
80#define MSKPHASE_3CHANNEL 0x09
81#define MSKPHASE_2CHANNEL 0x0A
82#define MSKPHASE_1CHANNEL 0x0B
83
84#define SLEW_RATE_CONTROL_MODE1_REG 0x15
85#define MSKPWM_DELAY_PHASE_ENABLE 0x04
86#define MSKPWM_DELAY_PHASE_DISABLE 0x00
87
88#define SLEW_RATE_CONTROL_MODE2_REG 0x16
89#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE 0xC0
90#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_DISABLE 0x00
91
92#define OPEN_SHORT_ENABLE_REG 0x17
93#define MSKOPEN_DETECTION_ENABLE (0x01 << 7)
94#define MSKOPEN_DETECTION_DISABLE (0x00)
95
96#define MSKSHORT_DETECTION_ENABLE (0x01 << 6)
97#define MSKSHORT_DETECTION_DISABLE (0x00)
98
99#define OPEN_SHORT_DUTY_REG 0x18
100#define OPEN_SHORT_FLAG_REG 0x19
101
102#define MSKOPEN_DETECTION_INTERRUPT_ENABLE (0x01 << 7)
103#define MSKOPEN_DETECTION_INTERRUPT_DISABLE (0x00)
104
105#define MSKSHORT_DETECTION_INTERRUPT_ENABLE (0x01 << 6)
106#define MSKSHORT_DETECTION_INTERRUPT_DISABLE (0x00)
107
108#define SOFTWARE_SLEEP_REG 0x1A
109#define MSKSLEEP_ENABLE 0x02
110#define MSKSLEEP_DISABLE 0x00
111
112// LED Control Registers
113#define LED_CONTROL_ON_OFF_FIRST_ADDR 0x0
114#define LED_CONTROL_ON_OFF_LAST_ADDR 0x17
115#define LED_CONTROL_ON_OFF_LENGTH ((LED_CONTROL_ON_OFF_LAST_ADDR - LED_CONTROL_ON_OFF_FIRST_ADDR) + 1)
116
117#define LED_CONTROL_OPEN_FIRST_ADDR 0x18
118#define LED_CONTROL_OPEN_LAST_ADDR 0x2F
119#define LED_CONTROL_OPEN_LENGTH ((LED_CONTROL_OPEN_LAST_ADDR - LED_CONTROL_OPEN_FIRST_ADDR) + 1)
120
121#define LED_CONTROL_SHORT_FIRST_ADDR 0x30
122#define LED_CONTROL_SHORT_LAST_ADDR 0x47
123#define LED_CONTROL_SHORT_LENGTH ((LED_CONTROL_SHORT_LAST_ADDR - LED_CONTROL_SHORT_FIRST_ADDR) + 1)
124
125#define LED_CONTROL_PAGE_LENGTH 0x48
126
127// LED Control Registers
128#define LED_PWM_FIRST_ADDR 0x00
129#define LED_PWM_LAST_ADDR 0xBF
130#define LED_PWM_LENGTH 0xC0
131
132// Current Tune Registers
133#define LED_CURRENT_TUNE_FIRST_ADDR 0x00
134#define LED_CURRENT_TUNE_LAST_ADDR 0x0B
135#define LED_CURRENT_TUNE_LENGTH 0x0C
136
137#define A_1 0x00
138#define A_2 0x01
139#define A_3 0x02
140#define A_4 0x03
141#define A_5 0x04
142#define A_6 0x05
143#define A_7 0x06
144#define A_8 0x07
145#define A_9 0x08
146#define A_10 0x09
147#define A_11 0x0A
148#define A_12 0x0B
149#define A_13 0x0C
150#define A_14 0x0D
151#define A_15 0x0E
152#define A_16 0x0F
153
154#define B_1 0x10
155#define B_2 0x11
156#define B_3 0x12
157#define B_4 0x13
158#define B_5 0x14
159#define B_6 0x15
160#define B_7 0x16
161#define B_8 0x17
162#define B_9 0x18
163#define B_10 0x19
164#define B_11 0x1A
165#define B_12 0x1B
166#define B_13 0x1C
167#define B_14 0x1D
168#define B_15 0x1E
169#define B_16 0x1F
170
171#define C_1 0x20
172#define C_2 0x21
173#define C_3 0x22
174#define C_4 0x23
175#define C_5 0x24
176#define C_6 0x25
177#define C_7 0x26
178#define C_8 0x27
179#define C_9 0x28
180#define C_10 0x29
181#define C_11 0x2A
182#define C_12 0x2B
183#define C_13 0x2C
184#define C_14 0x2D
185#define C_15 0x2E
186#define C_16 0x2F
187
188#define D_1 0x30
189#define D_2 0x31
190#define D_3 0x32
191#define D_4 0x33
192#define D_5 0x34
193#define D_6 0x35
194#define D_7 0x36
195#define D_8 0x37
196#define D_9 0x38
197#define D_10 0x39
198#define D_11 0x3A
199#define D_12 0x3B
200#define D_13 0x3C
201#define D_14 0x3D
202#define D_15 0x3E
203#define D_16 0x3F
204
205#define E_1 0x40
206#define E_2 0x41
207#define E_3 0x42
208#define E_4 0x43
209#define E_5 0x44
210#define E_6 0x45
211#define E_7 0x46
212#define E_8 0x47
213#define E_9 0x48
214#define E_10 0x49
215#define E_11 0x4A
216#define E_12 0x4B
217#define E_13 0x4C
218#define E_14 0x4D
219#define E_15 0x4E
220#define E_16 0x4F
221
222#define F_1 0x50
223#define F_2 0x51
224#define F_3 0x52
225#define F_4 0x53
226#define F_5 0x54
227#define F_6 0x55
228#define F_7 0x56
229#define F_8 0x57
230#define F_9 0x58
231#define F_10 0x59
232#define F_11 0x5A
233#define F_12 0x5B
234#define F_13 0x5C
235#define F_14 0x5D
236#define F_15 0x5E
237#define F_16 0x5F
238
239#define G_1 0x60
240#define G_2 0x61
241#define G_3 0x62
242#define G_4 0x63
243#define G_5 0x64
244#define G_6 0x65
245#define G_7 0x66
246#define G_8 0x67
247#define G_9 0x68
248#define G_10 0x69
249#define G_11 0x6A
250#define G_12 0x6B
251#define G_13 0x6C
252#define G_14 0x6D
253#define G_15 0x6E
254#define G_16 0x6F
255
256#define H_1 0x70
257#define H_2 0x71
258#define H_3 0x72
259#define H_4 0x73
260#define H_5 0x74
261#define H_6 0x75
262#define H_7 0x76
263#define H_8 0x77
264#define H_9 0x78
265#define H_10 0x79
266#define H_11 0x7A
267#define H_12 0x7B
268#define H_13 0x7C
269#define H_14 0x7D
270#define H_15 0x7E
271#define H_16 0x7F
272
273#define I_1 0x80
274#define I_2 0x81
275#define I_3 0x82
276#define I_4 0x83
277#define I_5 0x84
278#define I_6 0x85
279#define I_7 0x86
280#define I_8 0x87
281#define I_9 0x88
282#define I_10 0x89
283#define I_11 0x8A
284#define I_12 0x8B
285#define I_13 0x8C
286#define I_14 0x8D
287#define I_15 0x8E
288#define I_16 0x8F
289
290#define J_1 0x90
291#define J_2 0x91
292#define J_3 0x92
293#define J_4 0x93
294#define J_5 0x94
295#define J_6 0x95
296#define J_7 0x96
297#define J_8 0x97
298#define J_9 0x98
299#define J_10 0x99
300#define J_11 0x9A
301#define J_12 0x9B
302#define J_13 0x9C
303#define J_14 0x9D
304#define J_15 0x9E
305#define J_16 0x9F
306
307#define K_1 0xA0
308#define K_2 0xA1
309#define K_3 0xA2
310#define K_4 0xA3
311#define K_5 0xA4
312#define K_6 0xA5
313#define K_7 0xA6
314#define K_8 0xA7
315#define K_9 0xA8
316#define K_10 0xA9
317#define K_11 0xAA
318#define K_12 0xAB
319#define K_13 0xAC
320#define K_14 0xAD
321#define K_15 0xAE
322#define K_16 0xAF
323
324#define L_1 0xB0
325#define L_2 0xB1
326#define L_3 0xB2
327#define L_4 0xB3
328#define L_5 0xB4
329#define L_6 0xB5
330#define L_7 0xB6
331#define L_8 0xB7
332#define L_9 0xB8
333#define L_10 0xB9
334#define L_11 0xBA
335#define L_12 0xBB
336#define L_13 0xBC
337#define L_14 0xBD
338#define L_15 0xBE
339#define L_16 0xBF \ No newline at end of file
diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h
index 112dfaaae..af5ca9e79 100644
--- a/quantum/rgb_matrix/rgb_matrix.h
+++ b/quantum/rgb_matrix/rgb_matrix.h
@@ -33,6 +33,8 @@
33# include "is31fl3737.h" 33# include "is31fl3737.h"
34#elif defined(IS31FL3741) 34#elif defined(IS31FL3741)
35# include "is31fl3741.h" 35# include "is31fl3741.h"
36#elif defined(CKLED2001)
37# include "ckled2001.h"
36#elif defined(AW20216) 38#elif defined(AW20216)
37# include "aw20216.h" 39# include "aw20216.h"
38#elif defined(WS2812) 40#elif defined(WS2812)
diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c
index 949cc3661..130ca47a6 100644
--- a/quantum/rgb_matrix/rgb_matrix_drivers.c
+++ b/quantum/rgb_matrix/rgb_matrix_drivers.c
@@ -23,7 +23,7 @@
23 * be here if shared between boards. 23 * be here if shared between boards.
24 */ 24 */
25 25
26#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3737) || defined(IS31FL3741) 26#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3737) || defined(IS31FL3741) || defined(CKLED2001)
27# include "i2c_master.h" 27# include "i2c_master.h"
28 28
29// TODO: Remove this at some later date 29// TODO: Remove this at some later date
@@ -80,6 +80,18 @@ static void init(void) {
80 80
81# elif defined(IS31FL3741) 81# elif defined(IS31FL3741)
82 IS31FL3741_init(DRIVER_ADDR_1); 82 IS31FL3741_init(DRIVER_ADDR_1);
83
84# elif defined(CKLED2001)
85 CKLED2001_init(DRIVER_ADDR_1);
86# if defined(DRIVER_ADDR_2)
87 CKLED2001_init(DRIVER_ADDR_2);
88# if defined(DRIVER_ADDR_3)
89 CKLED2001_init(DRIVER_ADDR_3);
90# if defined(DRIVER_ADDR_4)
91 CKLED2001_init(DRIVER_ADDR_4);
92# endif
93# endif
94# endif
83# endif 95# endif
84 96
85 for (int index = 0; index < DRIVER_LED_TOTAL; index++) { 97 for (int index = 0; index < DRIVER_LED_TOTAL; index++) {
@@ -94,6 +106,8 @@ static void init(void) {
94 IS31FL3737_set_led_control_register(index, enabled, enabled, enabled); 106 IS31FL3737_set_led_control_register(index, enabled, enabled, enabled);
95# elif defined(IS31FL3741) 107# elif defined(IS31FL3741)
96 IS31FL3741_set_led_control_register(index, enabled, enabled, enabled); 108 IS31FL3741_set_led_control_register(index, enabled, enabled, enabled);
109# elif defined(CKLED2001)
110 CKLED2001_set_led_control_register(index, enabled, enabled, enabled);
97# endif 111# endif
98 } 112 }
99 113
@@ -130,6 +144,18 @@ static void init(void) {
130 144
131# elif defined(IS31FL3741) 145# elif defined(IS31FL3741)
132 IS31FL3741_update_led_control_registers(DRIVER_ADDR_1, 0); 146 IS31FL3741_update_led_control_registers(DRIVER_ADDR_1, 0);
147
148# elif defined(CKLED2001)
149 CKLED2001_update_led_control_registers(DRIVER_ADDR_1, 0);
150# if defined(DRIVER_ADDR_2)
151 CKLED2001_update_led_control_registers(DRIVER_ADDR_2, 1);
152# if defined(DRIVER_ADDR_3)
153 CKLED2001_update_led_control_registers(DRIVER_ADDR_3, 2);
154# if defined(DRIVER_ADDR_4)
155 CKLED2001_update_led_control_registers(DRIVER_ADDR_4, 3);
156# endif
157# endif
158# endif
133# endif 159# endif
134} 160}
135 161
@@ -204,6 +230,27 @@ const rgb_matrix_driver_t rgb_matrix_driver = {
204 .set_color = IS31FL3741_set_color, 230 .set_color = IS31FL3741_set_color,
205 .set_color_all = IS31FL3741_set_color_all, 231 .set_color_all = IS31FL3741_set_color_all,
206}; 232};
233
234# elif defined(CKLED2001)
235static void flush(void) {
236 CKLED2001_update_pwm_buffers(DRIVER_ADDR_1, 0);
237# if defined(DRIVER_ADDR_2)
238 CKLED2001_update_pwm_buffers(DRIVER_ADDR_2, 1);
239# if defined(DRIVER_ADDR_3)
240 CKLED2001_update_pwm_buffers(DRIVER_ADDR_3, 2);
241# if defined(DRIVER_ADDR_4)
242 CKLED2001_update_pwm_buffers(DRIVER_ADDR_4, 3);
243# endif
244# endif
245# endif
246}
247
248const rgb_matrix_driver_t rgb_matrix_driver = {
249 .init = init,
250 .flush = flush,
251 .set_color = CKLED2001_set_color,
252 .set_color_all = CKLED2001_set_color_all,
253};
207# endif 254# endif
208 255
209#elif defined(AW20216) 256#elif defined(AW20216)