Skip to content

Commit 91fe35e

Browse files
committed
Add seesaw neopixel
Signed-off-by: Titouan Christophe <[email protected]>
1 parent 80359a9 commit 91fe35e

File tree

5 files changed

+135
-0
lines changed

5 files changed

+135
-0
lines changed

drivers/led/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ zephyr_library_sources_ifdef(CONFIG_LP5562 lp5562.c)
2020
zephyr_library_sources_ifdef(CONFIG_LP5569 lp5569.c)
2121
zephyr_library_sources_ifdef(CONFIG_NCP5623 ncp5623.c)
2222
zephyr_library_sources_ifdef(CONFIG_PCA9633 pca9633.c)
23+
zephyr_library_sources_ifdef(CONFIG_SEESAW_NEOPIXEL seesaw_neopixel.c)
2324
zephyr_library_sources_ifdef(CONFIG_TLC59108 tlc59108.c)
2425
# zephyr-keep-sorted-stop
2526

drivers/led/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ source "drivers/led/Kconfig.ncp5623"
4141
source "drivers/led/Kconfig.npm1300"
4242
source "drivers/led/Kconfig.pca9633"
4343
source "drivers/led/Kconfig.pwm"
44+
source "drivers/led/Kconfig.seesaw_neopixel"
4445
source "drivers/led/Kconfig.tlc59108"
4546
source "drivers/led/Kconfig.xec"
4647
# zephyr-keep-sorted-stop
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright 2025 Titouan Chrisotphe
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config SEESAW_NEOPIXEL
5+
bool "Adafruit Seesaw neopixel leds over I2C"
6+
default y
7+
depends on MFD_SEESAW
8+
depends on DT_HAS_ADAFRUIT_SEESAW_NEOPIXEL_ENABLED
9+
help
10+
Enable support for Adafruit Seesaw neopixel leds

drivers/led/seesaw_neopixel.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright (c) 2025 Titouan Christophe
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT adafruit_seesaw_neopixel
8+
9+
#include <zephyr/drivers/led.h>
10+
#include <zephyr/drivers/mfd/mfd_seesaw.h>
11+
#include <zephyr/dt-bindings/led/led.h>
12+
13+
enum seesaw_mod_neopixel {
14+
NEOPIXEL_PIN = 0x01,
15+
NEOPIXEL_SPEED = 0x02,
16+
NEOPIXEL_BUF_LENGTH = 0x03,
17+
NEOPIXEL_BUF = 0x04,
18+
NEOPIXEL_SHOW = 0x05,
19+
};
20+
21+
struct seesaw_neopixel_config {
22+
const struct device *seesaw;
23+
size_t length;
24+
const uint8_t *color_mapping;
25+
uint8_t num_colors;
26+
uint8_t output_pin;
27+
};
28+
29+
static int seesaw_neopixel_set_color(const struct device *dev, uint32_t led, uint8_t num_colors,
30+
const uint8_t *color)
31+
{
32+
int ret;
33+
const struct seesaw_neopixel_config *config = dev->config;
34+
uint16_t offset = config->num_colors * led;
35+
uint8_t buf[6] = {offset >> 8, offset & 0xff};
36+
37+
if (led >= config->length || num_colors != config->num_colors) {
38+
return -EINVAL;
39+
}
40+
41+
memcpy(buf + 2, color, num_colors);
42+
43+
ret = seesaw_write(config->seesaw, SEESAW_MOD_NEOPIXEL, NEOPIXEL_BUF, buf, 2 + num_colors);
44+
if (ret) {
45+
return ret;
46+
}
47+
48+
return seesaw_cmd(config->seesaw, SEESAW_MOD_NEOPIXEL, NEOPIXEL_SHOW);
49+
}
50+
51+
static int seesaw_neopixel_set_brightness(const struct device *dev, uint32_t led, uint8_t value)
52+
{
53+
const struct seesaw_neopixel_config *config = dev->config;
54+
uint8_t b = 255 * value / 100;
55+
uint8_t color[] = {b, b, b, b};
56+
57+
if (value > 100) {
58+
return -EINVAL;
59+
}
60+
61+
return seesaw_neopixel_set_color(dev, led, config->num_colors, color);
62+
}
63+
64+
static int seesaw_neopixel_on(const struct device *dev, uint32_t led)
65+
{
66+
return seesaw_neopixel_set_brightness(dev, led, 100);
67+
}
68+
69+
static int seesaw_neopixel_off(const struct device *dev, uint32_t led)
70+
{
71+
return seesaw_neopixel_set_brightness(dev, led, 0);
72+
}
73+
74+
static int seesaw_neopixel_init(const struct device *dev)
75+
{
76+
const struct seesaw_neopixel_config *config = dev->config;
77+
int ret = seesaw_claim_module(config->seesaw, SEESAW_MOD_NEOPIXEL, dev);
78+
79+
if (ret) {
80+
return ret;
81+
}
82+
83+
seesaw_write(config->seesaw, SEESAW_MOD_NEOPIXEL, NEOPIXEL_PIN, &config->output_pin, 1);
84+
seesaw_write_uint16(config->seesaw, SEESAW_MOD_NEOPIXEL, NEOPIXEL_BUF_LENGTH, 3 * config->length);
85+
86+
return 0;
87+
}
88+
89+
static DEVICE_API(led, seesaw_neopixel_api) = {
90+
.on = seesaw_neopixel_on,
91+
.off = seesaw_neopixel_off,
92+
.set_brightness = seesaw_neopixel_set_brightness,
93+
.set_color = seesaw_neopixel_set_color,
94+
};
95+
96+
#define SEESAW_NEOPIXEL_INIT(inst) \
97+
static const uint8_t cmap_##idx[] = DT_INST_PROP(inst, color_mapping); \
98+
static const struct seesaw_neopixel_config config_##inst = { \
99+
.seesaw = DEVICE_DT_GET(DT_INST_PARENT(inst)), \
100+
.length = DT_INST_PROP(inst, chain_length), \
101+
.color_mapping = cmap_##idx, \
102+
.num_colors = sizeof(cmap_##idx), \
103+
.output_pin = DT_INST_PROP(inst, output_pin), \
104+
}; \
105+
DEVICE_DT_INST_DEFINE(inst, seesaw_neopixel_init, NULL, NULL, &config_##inst, POST_KERNEL, \
106+
CONFIG_LED_INIT_PRIORITY, &seesaw_neopixel_api);
107+
108+
DT_INST_FOREACH_STATUS_OKAY(SEESAW_NEOPIXEL_INIT)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright (c) 2025 Titouan Christophe
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Adafruit Seesaw neopixel output
5+
6+
compatible: "adafruit,seesaw-neopixel"
7+
8+
include: [led-strip.yaml]
9+
10+
properties:
11+
output-pin:
12+
required: true
13+
type: int
14+
description: |
15+
Neopixel output pin number

0 commit comments

Comments
 (0)