aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2021-07-27 23:55:51 +0100
committerGitHub <noreply@github.com>2021-07-27 23:55:51 +0100
commit3858a784c702d75d207e62c6cdf4449eed41c789 (patch)
tree17713862786ea5951f7fb15605df7e2082fdc34b /drivers
parent56443fe3cf19768f34e065319d50164d4e99dd3c (diff)
downloadqmk_firmware-3858a784c702d75d207e62c6cdf4449eed41c789.tar.gz
qmk_firmware-3858a784c702d75d207e62c6cdf4449eed41c789.zip
Align AW20216 driver (#13712)
* Align AW20216 driver * Update drivers/awinic/aw20216.h Co-authored-by: Ryan <fauxpark@gmail.com> * Review comments * formatting fixes * stop if start failed? * review comments Co-authored-by: Ryan <fauxpark@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/awinic/aw20216.c131
-rw-r--r--drivers/awinic/aw20216.h5
2 files changed, 48 insertions, 88 deletions
diff --git a/drivers/awinic/aw20216.c b/drivers/awinic/aw20216.c
index 776653fa6..c608c0ab4 100644
--- a/drivers/awinic/aw20216.c
+++ b/drivers/awinic/aw20216.c
@@ -45,8 +45,6 @@
45 45
46#define AW_PWM_REGISTER_COUNT 216 46#define AW_PWM_REGISTER_COUNT 216
47 47
48#define AW_SPI_START(PIN) spi_start(PIN, false, 0, AW_SPI_DIVISOR)
49
50#ifndef AW_SCALING_MAX 48#ifndef AW_SCALING_MAX
51# define AW_SCALING_MAX 150 49# define AW_SCALING_MAX 150
52#endif 50#endif
@@ -55,128 +53,89 @@
55# define AW_GLOBAL_CURRENT_MAX 150 53# define AW_GLOBAL_CURRENT_MAX 150
56#endif 54#endif
57 55
58#ifndef DRIVER_1_CS
59# define DRIVER_1_CS B13
60#endif
61
62#ifndef DRIVER_1_EN
63# define DRIVER_1_EN C13
64#endif
65
66#ifndef AW_SPI_DIVISOR 56#ifndef AW_SPI_DIVISOR
67# define AW_SPI_DIVISOR 4 57# define AW_SPI_DIVISOR 4
68#endif 58#endif
69 59
70uint8_t g_spi_transfer_buffer[3] = {0};
71uint8_t g_pwm_buffer[DRIVER_COUNT][AW_PWM_REGISTER_COUNT]; 60uint8_t g_pwm_buffer[DRIVER_COUNT][AW_PWM_REGISTER_COUNT];
72bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; 61bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false};
73 62
74bool AW20216_write_register(pin_t slave_pin, uint8_t page, uint8_t reg, uint8_t data) { 63bool AW20216_write(pin_t cs_pin, uint8_t page, uint8_t reg, uint8_t* data, uint8_t len) {
75 // Do we need to call spi_stop() if this fails? 64 static uint8_t s_spi_transfer_buffer[2] = {0};
76 if (!AW_SPI_START(slave_pin)) { 65
66 if (!spi_start(cs_pin, false, 0, AW_SPI_DIVISOR)) {
67 spi_stop();
77 return false; 68 return false;
78 } 69 }
79 70
80 g_spi_transfer_buffer[0] = (AWINIC_ID | page | AW_WRITE); 71 s_spi_transfer_buffer[0] = (AWINIC_ID | page | AW_WRITE);
81 g_spi_transfer_buffer[1] = reg; 72 s_spi_transfer_buffer[1] = reg;
82 g_spi_transfer_buffer[2] = data;
83 73
84 if (spi_transmit(g_spi_transfer_buffer, 3) != SPI_STATUS_SUCCESS) { 74 if (spi_transmit(s_spi_transfer_buffer, 2) != SPI_STATUS_SUCCESS) {
85 spi_stop(); 75 spi_stop();
86 return false; 76 return false;
87 } 77 }
78
79 if (spi_transmit(data, len) != SPI_STATUS_SUCCESS) {
80 spi_stop();
81 return false;
82 }
83
88 spi_stop(); 84 spi_stop();
89 return true; 85 return true;
90} 86}
91 87
92bool AW20216_init_scaling(void) { 88static inline bool AW20216_write_register(pin_t cs_pin, uint8_t page, uint8_t reg, uint8_t value) {
89 // Little wrapper so callers need not care about sending a buffer
90 return AW20216_write(cs_pin, page, reg, &value, 1);
91}
92
93static void AW20216_init_scaling(pin_t cs_pin) {
93 // Set constant current to the max, control brightness with PWM 94 // Set constant current to the max, control brightness with PWM
94 aw_led led; 95 for (uint8_t i = 0; i < AW_PWM_REGISTER_COUNT; i++) {
95 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { 96 AW20216_write_register(cs_pin, AW_PAGE_SCALING, i, AW_SCALING_MAX);
96 led = g_aw_leds[i];
97 if (led.driver == 0) {
98 AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.r, AW_SCALING_MAX);
99 AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.g, AW_SCALING_MAX);
100 AW20216_write_register(DRIVER_1_CS, AW_PAGE_SCALING, led.b, AW_SCALING_MAX);
101 }
102#ifdef DRIVER_2_CS
103 else if (led.driver == 1) {
104 AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.r, AW_SCALING_MAX);
105 AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.g, AW_SCALING_MAX);
106 AW20216_write_register(DRIVER_2_CS, AW_PAGE_SCALING, led.b, AW_SCALING_MAX);
107 }
108#endif
109 } 97 }
110 return true;
111} 98}
112 99
113bool AW20216_soft_enable(void) { 100static inline void AW20216_init_current_limit(pin_t cs_pin) {
114 AW20216_write_register(DRIVER_1_CS, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN); 101 // Push config
115#ifdef DRIVER_2_CS 102 AW20216_write_register(cs_pin, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX);
116 AW20216_write_register(DRIVER_2_CS, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN);
117#endif
118 return true;
119} 103}
120 104
121void AW20216_update_pwm(int index, uint8_t red, uint8_t green, uint8_t blue) { 105static inline void AW20216_soft_enable(pin_t cs_pin) {
122 aw_led led = g_aw_leds[index]; 106 // Push config
123 if (led.driver == 0) { 107 AW20216_write_register(cs_pin, AW_PAGE_FUNCTION, AW_REG_CONFIGURATION, AW_CONFIG_DEFAULT | AW_CHIPEN);
124 AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.r, red);
125 AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.g, green);
126 AW20216_write_register(DRIVER_1_CS, AW_PAGE_PWM, led.b, blue);
127 }
128#ifdef DRIVER_2_CS
129 else if (led.driver == 1) {
130 AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.r, red);
131 AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.g, green);
132 AW20216_write_register(DRIVER_2_CS, AW_PAGE_PWM, led.b, blue);
133 }
134#endif
135 return;
136} 108}
137 109
138void AW20216_init(void) { 110void AW20216_init(pin_t cs_pin, pin_t en_pin) {
139 // All LEDs should start with all scaling and PWM registers as off 111 setPinOutput(en_pin);
140 setPinOutput(DRIVER_1_EN); 112 writePinHigh(en_pin);
141 writePinHigh(DRIVER_1_EN); 113
142 AW20216_write_register(DRIVER_1_CS, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX); 114 // Drivers should start with all scaling and PWM registers as off
143#ifdef DRIVER_2_EN 115 AW20216_init_current_limit(cs_pin);
144 setPinOutput(DRIVER_2_EN); 116 AW20216_init_scaling(cs_pin);
145 writePinHigh(DRIVER_2_EN); 117
146 AW20216_write_register(DRIVER_2_CS, AW_PAGE_FUNCTION, AW_REG_GLOBALCURRENT, AW_GLOBAL_CURRENT_MAX); 118 AW20216_soft_enable(cs_pin);
147#endif
148 AW20216_init_scaling();
149 AW20216_soft_enable();
150 return;
151} 119}
152 120
153void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { 121void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
154 aw_led led = g_aw_leds[index]; 122 aw_led led = g_aw_leds[index];
123
155 g_pwm_buffer[led.driver][led.r] = red; 124 g_pwm_buffer[led.driver][led.r] = red;
156 g_pwm_buffer[led.driver][led.g] = green; 125 g_pwm_buffer[led.driver][led.g] = green;
157 g_pwm_buffer[led.driver][led.b] = blue; 126 g_pwm_buffer[led.driver][led.b] = blue;
158 g_pwm_buffer_update_required[led.driver] = true; 127 g_pwm_buffer_update_required[led.driver] = true;
159 return;
160} 128}
129
161void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { 130void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
162 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) { 131 for (uint8_t i = 0; i < DRIVER_LED_TOTAL; i++) {
163 AW20216_set_color(i, red, green, blue); 132 AW20216_set_color(i, red, green, blue);
164 } 133 }
165 return;
166}
167
168void AW20216_write_pwm_buffer(pin_t slave_pin, uint8_t buffer_idx) {
169 AW_SPI_START(slave_pin);
170 spi_write((AWINIC_ID | AW_PAGE_PWM | AW_WRITE));
171 spi_write(0);
172 spi_transmit(g_pwm_buffer[buffer_idx], AW_PWM_REGISTER_COUNT);
173 spi_stop();
174} 134}
175 135
176void AW20216_update_pwm_buffers(void) { 136void AW20216_update_pwm_buffers(pin_t cs_pin, uint8_t index) {
177 AW20216_write_pwm_buffer(DRIVER_1_CS, 0); 137 if (g_pwm_buffer_update_required[index]) {
178#ifdef DRIVER_2_CS 138 AW20216_write(cs_pin, AW_PAGE_PWM, 0, g_pwm_buffer[index], AW_PWM_REGISTER_COUNT);
179 AW20216_write_pwm_buffer(DRIVER_2_CS, 1); 139 }
180#endif 140 g_pwm_buffer_update_required[index] = false;
181 return;
182} 141}
diff --git a/drivers/awinic/aw20216.h b/drivers/awinic/aw20216.h
index 9c6865cc8..c55d9605f 100644
--- a/drivers/awinic/aw20216.h
+++ b/drivers/awinic/aw20216.h
@@ -18,6 +18,7 @@
18 18
19#include <stdint.h> 19#include <stdint.h>
20#include <stdbool.h> 20#include <stdbool.h>
21#include "gpio.h"
21 22
22typedef struct aw_led { 23typedef struct aw_led {
23 uint8_t driver : 2; 24 uint8_t driver : 2;
@@ -28,10 +29,10 @@ typedef struct aw_led {
28 29
29extern const aw_led g_aw_leds[DRIVER_LED_TOTAL]; 30extern const aw_led g_aw_leds[DRIVER_LED_TOTAL];
30 31
31void AW20216_init(void); 32void AW20216_init(pin_t cs_pin, pin_t en_pin);
32void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); 33void AW20216_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
33void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue); 34void AW20216_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
34void AW20216_update_pwm_buffers(void); 35void AW20216_update_pwm_buffers(pin_t cs_pin, uint8_t index);
35 36
36#define CS1_SW1 0x00 37#define CS1_SW1 0x00
37#define CS2_SW1 0x01 38#define CS2_SW1 0x01