summaryrefslogtreecommitdiff
path: root/driver/led/tlc59116f.c
diff options
context:
space:
mode:
authorFiras Sammoura <fsammoura@google.com>2022-06-17 16:40:54 +0000
committerFiras Sammoura <fsammoura@google.com>2022-06-17 16:40:54 +0000
commite5fb0b9ba488614b5684e640530f00821ab7b943 (patch)
tree9a15b4a98d7987870a1805a33883d0cf9123fc05 /driver/led/tlc59116f.c
parentad46fafb27c419bd416bfecc76df6c6426a99b32 (diff)
parenta46d3f3feaac0d69012f61b66f652bff991d05a7 (diff)
downloadchrome-ec-e5fb0b9ba488614b5684e640530f00821ab7b943.tar.gz
Merge remote-tracking branch cros/main into firmware-fpmcu-bloonchipper-release
Generated by: ./util/update_release_branch.py --board bloonchipper --relevant_paths_file ./util/fingerprint-relevant-paths.txt firmware-fpmcu-bloonchipper-release Relevant changes: git log --oneline ad46fafb27..a46d3f3fea -- board/hatch_fp board/bloonchipper common/fpsensor docs/fingerprint driver/fingerprint util/getversion.sh 981fb88cf8 docs/fingerprint: Resolve contradictory FPMCU factory flashing instructions 38ef6b7306 tree: Files should end with single newline 60032a8828 docs/fingerprint: Clean up formatting in fingerprint-factory-quick-guide.md f49eb6f894 docs/fingerprint: Run mdformat 64aa5fc7bb docs/fingerprint: Add links to info on fuzz testing 8bd99cc434 fpsensor: Use correct return type 2b2d7a991d fpsensor: Use correct return type BRANCH=None BUG=b:234772776 b:234181908 b:172020503 b:234181908 TEST=`make -j buildall` Cq-Include-Trybots: chromeos/cq:cq-orchestrator Signed-off-by: Firas Sammoura <fsammoura@google.com> Change-Id: I18b58de542c8b439d0f9327a7d4f0ec897da080f
Diffstat (limited to 'driver/led/tlc59116f.c')
-rw-r--r--driver/led/tlc59116f.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/driver/led/tlc59116f.c b/driver/led/tlc59116f.c
new file mode 100644
index 0000000000..b1c16a921b
--- /dev/null
+++ b/driver/led/tlc59116f.c
@@ -0,0 +1,129 @@
+/* Copyright 2022 The ChromiumOS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <string.h>
+
+#include "common.h"
+#include "console.h"
+#include "i2c.h"
+#include "rgb_keyboard.h"
+#include "stddef.h"
+#include "tlc59116f.h"
+
+#define CPRINTF(fmt, args...) cprintf(CC_RGBKBD, "TLC59116F: " fmt, ##args)
+#define CPRINTS(fmt, args...) cprints(CC_RGBKBD, "TLC59116F: " fmt, ##args)
+
+#define TLC59116F_BUF_SIZE (SIZE_OF_RGB * TLC59116F_GRID_SIZE)
+#define TLC59116_MODE_BIT_SLEEP 4
+
+static int tlc59116f_read(struct rgbkbd *ctx, uint8_t addr, uint8_t *value)
+{
+ return i2c_xfer(ctx->cfg->i2c, TLC59116F_I2C_ADDR_FLAG,
+ &addr, sizeof(addr), value, sizeof(*value));
+}
+
+static int tlc59116f_write(struct rgbkbd *ctx, uint8_t addr, uint8_t value)
+{
+ uint8_t buf[2] = {
+ [0] = addr,
+ [1] = value,
+ };
+
+ return i2c_xfer(ctx->cfg->i2c, TLC59116F_I2C_ADDR_FLAG,
+ buf, sizeof(buf), NULL, 0);
+}
+
+static int tlc59116f_reset(struct rgbkbd *ctx)
+{
+ return i2c_write8(ctx->cfg->i2c, TLC59116F_RESET, 0xA5, 0x5A);
+}
+
+static int tlc59116f_init(struct rgbkbd *ctx)
+{
+ int i, rv;
+
+ for (i = TLC59116F_LEDOUT0; i <= TLC59116F_LEDOUT3; i++) {
+ rv = tlc59116f_write(ctx, i, TLC59116_LEDOUT_PWM);
+ if (rv) {
+ return rv;
+ }
+ }
+
+ rv = tlc59116f_write(ctx, TLC59116F_MODE1, 0x01);
+ if (rv) {
+ CPRINTS("Failed to set TLC59116F normal mode");
+ return rv;
+ }
+
+ return EC_SUCCESS;
+}
+
+static int tlc59116f_enable(struct rgbkbd *ctx, bool enable)
+{
+ uint8_t cfg;
+ int rv;
+
+ rv = tlc59116f_read(ctx, TLC59116F_MODE1, &cfg);
+ if (rv) {
+ CPRINTS("Failed to enable TLC59116F");
+ return rv;
+ }
+
+ WRITE_BIT(cfg, TLC59116_MODE_BIT_SLEEP, !enable);
+ return tlc59116f_write(ctx, TLC59116F_MODE1, cfg);
+}
+
+static int tlc59116f_set_color(struct rgbkbd *ctx, uint8_t offset,
+ struct rgb_s *color, uint8_t len)
+{
+ uint8_t buf[sizeof(offset) + TLC59116F_BUF_SIZE];
+ const int frame_len = len * SIZE_OF_RGB + sizeof(offset);
+ const int frame_offset = offset * SIZE_OF_RGB;
+ int i;
+
+ if (frame_offset + frame_len > sizeof(buf)) {
+ return EC_ERROR_OVERFLOW;
+ }
+
+ buf[0] = TLC59116_AI_BRIGHTNESS_ONLY |
+ (frame_offset + TLC59116F_PWM0);
+ for (i = 0; i < len; i++) {
+ buf[i * SIZE_OF_RGB + 1] = color[i].r;
+ buf[i * SIZE_OF_RGB + 2] = color[i].g;
+ buf[i * SIZE_OF_RGB + 3] = color[i].b;
+ }
+
+ return i2c_xfer(ctx->cfg->i2c, TLC59116F_I2C_ADDR_FLAG,
+ buf, frame_len, NULL, 0);
+}
+
+static int tlc59116f_set_scale(struct rgbkbd *ctx, uint8_t offset,
+ struct rgb_s scale, uint8_t len)
+{
+ /* tlc59116f not support scale function */
+ return EC_SUCCESS;
+}
+
+static int tlc59116f_set_gcc(struct rgbkbd *ctx, uint8_t level)
+{
+ int j, rv;
+
+ for (j = TLC59116F_LEDOUT0; j <= TLC59116F_LEDOUT3; j++) {
+ rv = tlc59116f_write(ctx, j, TLC59116_LEDOUT_GROUP);
+ if (rv) {
+ return rv;
+ }
+ }
+
+ return tlc59116f_write(ctx, TLC59116F_GRPPWM, level);
+}
+
+const struct rgbkbd_drv tlc59116f_drv = {
+ .reset = tlc59116f_reset,
+ .init = tlc59116f_init,
+ .enable = tlc59116f_enable,
+ .set_color = tlc59116f_set_color,
+ .set_scale = tlc59116f_set_scale,
+ .set_gcc = tlc59116f_set_gcc,
+};