Skip to content

Commit 64c79de

Browse files
committed
drivers: led: is31fl319x add is31fl3197 support
Add the registers and the like to the .c file plus add a Kconf file plus bindings. Updated example sketch: It manually computes which channel maps to red, green and blue and then uses those indexes to map the table of colors to the right channels. Signed-off-by: Kurt Eckhardt <[email protected]>
1 parent 63be162 commit 64c79de

File tree

7 files changed

+249
-25
lines changed

7 files changed

+249
-25
lines changed

drivers/led/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ zephyr_library()
77
# zephyr-keep-sorted-start
88
zephyr_library_sources_ifdef(CONFIG_HT16K33 ht16k33.c)
99
zephyr_library_sources_ifdef(CONFIG_IS31FL3194 is31fl319x.c)
10+
zephyr_library_sources_ifdef(CONFIG_IS31FL3197 is31fl319x.c)
1011
zephyr_library_sources_ifdef(CONFIG_IS31FL3216A is31fl3216a.c)
1112
zephyr_library_sources_ifdef(CONFIG_IS31FL3733 is31fl3733.c)
1213
zephyr_library_sources_ifdef(CONFIG_LEDS_GROUP_MULTICOLOR leds_group_multicolor.c)

drivers/led/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ source "drivers/led/Kconfig.dac"
3232
source "drivers/led/Kconfig.gpio"
3333
source "drivers/led/Kconfig.ht16k33"
3434
source "drivers/led/Kconfig.is31fl3194"
35+
source "drivers/led/Kconfig.is31fl3197"
3536
source "drivers/led/Kconfig.is31fl3216a"
3637
source "drivers/led/Kconfig.is31fl3733"
3738
source "drivers/led/Kconfig.leds-group-multicolor"

drivers/led/Kconfig.is31fl3197

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2024 Arduino SA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config IS31FL3197
5+
bool "IS31FL3197 LED driver"
6+
default y
7+
depends on DT_HAS_ISSI_IS31FL3197_ENABLED
8+
select I2C
9+
help
10+
Enable LED driver for Lumissil Microsystems (a division of ISSI)
11+
IS31FL3197. This chip supports one RGB LED or 4 independent LEDs.

drivers/led/is31fl319x.c

Lines changed: 79 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,16 @@ struct is31f1319x_model {
3838
const uint8_t led_channels[];
3939
};
4040

41+
struct is31fl319x_config {
42+
struct i2c_dt_spec bus;
43+
uint8_t channel_count;
44+
uint8_t num_leds;
45+
const struct led_info *led_infos;
46+
const uint8_t *current_limits;
47+
const struct is31f1319x_model *regs;
48+
};
4149

50+
/* IS31FL3194 model registers and values */
4251
#define IS31FL3194_PROD_ID_REG 0x00
4352
#define IS31FL3194_CONF_REG 0x01
4453
#define IS31FL3194_CURRENT_REG 0x03
@@ -53,6 +62,7 @@ struct is31f1319x_model {
5362

5463
#define IS31FL3194_CHANNEL_COUNT 3
5564

65+
#ifdef CONFIG_IS31FL3194
5666
static const struct is31f1319x_model is31f13194_model = {
5767
/* register indexes */
5868
.prod_id_reg = IS31FL3194_PROD_ID_REG,
@@ -69,15 +79,44 @@ static const struct is31f1319x_model is31f13194_model = {
6979

7080
/* channel output registers */
7181
.led_channels = {IS31FL3194_OUT1_REG, IS31FL3194_OUT2_REG, IS31FL3194_OUT3_REG}};
82+
#endif
83+
84+
/* IS31FL3197 model registers and values */
85+
#define IS31FL3197_PROD_ID_REG 0x00
86+
#define IS31FL3197_SHUTDOWN_REG 0x01
87+
#define IS31FL3197_OPER_CONFIG_REG 0x02
88+
#define IS31FL3197_OUT1_REG 0x10
89+
#define IS31FL3197_OUT2_REG 0x11
90+
#define IS31FL3197_OUT3_REG 0x12
91+
#define IS31FL3197_OUT4_REG 0x13
92+
#define IS31FL3197_UPDATE_REG 0x2b
93+
94+
#define IS31FL3197_SHUTDOWN_REG_VAL 0xf1 /* enable all channels */
95+
#define IS31FL3197_OPER_CONFIG_REG_VAL 0xff /* set all to current level */
96+
#define IS31FL3197_UPDATE_VAL 0xc5
97+
98+
#define IS31FL3197_CHANNEL_COUNT 4
99+
100+
#ifdef CONFIG_IS31FL3197
101+
static const struct is31f1319x_model is31f13197_model = {
102+
/* register indexes */
103+
.prod_id_reg = IS31FL3197_PROD_ID_REG,
104+
.shutdown_reg = IS31FL3197_SHUTDOWN_REG,
105+
.conf_reg = IS31FL3197_OPER_CONFIG_REG,
106+
.current_reg = REG_NOT_DEFINED,
107+
.update_reg = IS31FL3197_UPDATE_REG,
72108

73-
struct is31fl319x_config {
74-
struct i2c_dt_spec bus;
75-
uint8_t channel_count;
76-
uint8_t num_leds;
77-
const struct led_info *led_infos;
78-
const uint8_t *current_limits;
79-
const struct is31f1319x_model *regs;
109+
/* values for those registers */
110+
.prod_id_val = 0xff,
111+
.shutdown_reg_val = IS31FL3197_SHUTDOWN_REG_VAL,
112+
.conf_enable = IS31FL3197_OPER_CONFIG_REG_VAL,
113+
.update_val = IS31FL3197_UPDATE_VAL,
114+
115+
/* channel output registers */
116+
.led_channels = {IS31FL3197_OUT1_REG, IS31FL3197_OUT2_REG, IS31FL3197_OUT3_REG,
117+
IS31FL3197_OUT4_REG}
80118
};
119+
#endif
81120

82121
static const struct led_info *is31fl319x_led_to_info(const struct is31fl319x_config *config,
83122
uint32_t led)
@@ -124,7 +163,7 @@ static int is31fl319x_write_channels(const struct device *dev, uint32_t start_ch
124163
{
125164
const struct is31fl319x_config *config = dev->config;
126165
const struct is31f1319x_model *regs = config->regs;
127-
int ret;
166+
int ret = 0;
128167

129168
if ((start_channel + num_channels) > config->channel_count) {
130169
return -ENOTSUP;
@@ -210,10 +249,9 @@ static int is31fl319x_check_config(const struct device *dev)
210249
const struct is31fl319x_config *config = dev->config;
211250
const struct led_info *info;
212251
uint8_t rgb_count = 0;
213-
uint8_t i;
214252

215253
/* verify that number of leds defined is not > number of channels */
216-
for (i = 0; i < config->num_leds; i++) {
254+
for (int i = 0; i < config->num_leds; i++) {
217255
info = &config->led_infos[i];
218256
rgb_count += info->num_colors;
219257
}
@@ -230,7 +268,7 @@ static int is31fl319x_init(const struct device *dev)
230268
const struct is31fl319x_config *config = dev->config;
231269
const struct led_info *info = NULL;
232270
const struct is31f1319x_model *regs = config->regs;
233-
int i, j, ret;
271+
int ret;
234272
uint8_t prod_id, band, channel;
235273
uint8_t current_reg = 0;
236274

@@ -250,20 +288,30 @@ static int is31fl319x_init(const struct device *dev)
250288
return ret;
251289
}
252290

253-
if (prod_id != regs->prod_id_val) {
254-
LOG_ERR("%s: invalid product ID 0x%02x (expected 0x%02x)", dev->name, prod_id,
255-
regs->prod_id_val);
256-
return -ENODEV;
291+
if (regs->prod_id_val != 0xff) {
292+
if (prod_id != regs->prod_id_val) {
293+
LOG_ERR("%s: invalid product ID 0x%02x (expected 0x%02x)", dev->name,
294+
prod_id, regs->prod_id_val);
295+
return -ENODEV;
296+
}
297+
} else {
298+
299+
/* The product ID (8 bit) should be the I2C address(7 bit) */
300+
if (prod_id != (config->bus.addr << 1)) {
301+
LOG_ERR("%s: invalid product ID 0x%02x (expected 0x%02x)", dev->name,
302+
prod_id, config->bus.addr << 1);
303+
return -ENODEV;
304+
}
257305
}
258306

259307
/* calc current limit register value */
260308
if (regs->current_reg != REG_NOT_DEFINED) {
261309
channel = 0;
262-
for (i = 0; i < config->num_leds; i++) {
310+
for (int i = 0; i < config->num_leds; i++) {
263311
info = &config->led_infos[i];
264312
band = (config->current_limits[i] / 10) - 1;
265313

266-
for (j = 0; j < info->num_colors; j++) {
314+
for (int j = 0; j < info->num_colors; j++) {
267315
current_reg |= band << (2 * channel);
268316
channel++;
269317
}
@@ -275,6 +323,15 @@ static int is31fl319x_init(const struct device *dev)
275323
return ret;
276324
}
277325
}
326+
if (regs->shutdown_reg != REG_NOT_DEFINED) {
327+
ret = i2c_reg_write_byte_dt(&config->bus, regs->shutdown_reg,
328+
regs->shutdown_reg_val);
329+
if (ret != 0) {
330+
LOG_ERR("%s: failed to set current limit", dev->name);
331+
return ret;
332+
}
333+
}
334+
278335
/* enable device */
279336
return i2c_reg_write_byte_dt(&config->bus, regs->conf_reg,
280337
regs->conf_enable);
@@ -329,3 +386,8 @@ static DEVICE_API(led, is31fl319x_led_api) = {
329386
#define DT_DRV_COMPAT issi_is31fl3194
330387
DT_INST_FOREACH_STATUS_OKAY_VARGS(IS31FL319X_DEVICE, 4, IS31FL3194_CHANNEL_COUNT,
331388
&is31f13194_model)
389+
#undef DT_DRV_COMPAT
390+
#define DT_DRV_COMPAT issi_is31fl3197
391+
DT_INST_FOREACH_STATUS_OKAY_VARGS(IS31FL319X_DEVICE, 7, IS31FL3194_CHANNEL_COUNT,
392+
&is31f13197_model)
393+
#undef DT_DRV_COMPAT
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Copyright (c) 2024 Arduino SA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: |
5+
IS31FL3197 4-channel LED driver with programmable pattern sequencing
6+
7+
This driver supports single-channel and RGB LEDs. For single channel LEDs,
8+
the led_set_brightness() API can be used to set the brightness of each LED.
9+
For RGB LEDs, the led_set_color() API can be used to set the red, green and
10+
blue components; the driver takes care of routing to the outputs described
11+
by the color-mapping property.
12+
13+
The LED_SHELL application can be used for testing.
14+
15+
The following shows configuration for Arduino Giga Display shield
16+
17+
This driver supports single-channel and RGB and maybe RGBW LEDs. For single
18+
channel LEDs, the led_set_brightness() API can be used to set the brightness
19+
of each LED. For RGB LEDs, the led_set_color() API can be used to set the red,
20+
green and blue and white components; the driver takes care of routing to the
21+
outputs described by the color-mapping property.
22+
23+
The LED_SHELL application can be used for testing.
24+
25+
The following defines a single RGB LED in the is31fl3197 DT node:
26+
27+
is31fl3197@50 {
28+
compatible = "issi,is31fl3197";
29+
reg = <0x50>;
30+
31+
led_0 {
32+
label = "RGB LED";
33+
color-mapping =
34+
<LED_COLOR_ID_RED>,
35+
<LED_COLOR_ID_GREEN>,
36+
<LED_COLOR_ID_BLUE>;
37+
};
38+
};
39+
40+
The following example defines three single-channel LEDs in the is31fl3197 DT node:
41+
42+
is31fl3197@50 {
43+
compatible = "issi,is31fl3197";
44+
reg = <0x50>;
45+
46+
led_0 {
47+
label = "RED LED";
48+
color-mapping = <LED_COLOR_ID_RED>;
49+
};
50+
51+
led_1 {
52+
label = "GREEN LED";
53+
color-mapping = <LED_COLOR_ID_GREEN>;
54+
};
55+
56+
led_2 {
57+
label = "BLUE LED";
58+
color-mapping = <LED_COLOR_ID_BLUE>;
59+
};
60+
};
61+
62+
compatible: "issi,is31fl3197"
63+
64+
include: ["i2c-device.yaml", "led-controller.yaml"]
65+
66+
child-binding:
67+
properties:
68+
label:
69+
required: true
70+
71+
color-mapping:
72+
required: true
73+
74+
current-limit:
75+
type: int
76+
default: 10
77+
enum:
78+
- 10
79+
description: |
80+
The current limit for the LED in mA.
Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,45 @@
1-
.. zephyr:code-sample:: is31fl3194
1+
.. zephyr:code-sample:: is31fl319x
22
:name: IS31FL3194 RGB LED
33
:relevant-api: led_interface
44

5-
Cycle colors on an RGB LED connected to the IS31FL3194 using the LED API.
5+
Cycle colors on an RGB LED connected to the IS31FL3194 or IS31FL3197
6+
using the LED API.
67

78
Overview
89
********
910

10-
This sample cycles several colors on an RGB LED forever using the LED API.
11+
This sample first looks through the color table to map which channels
12+
map to Red, Green and Blue. It then fade in and out each of these colors
13+
one at a time. It then cycles through several colors on an RGB LED
14+
forever using the LED API. For each of these colors it maps the Red,
15+
Green and Blue colors to the appropriate channels.
1116

1217
Building and Running
1318
********************
1419

1520
This sample can be built and executed on an Arduino Nicla Sense ME, or on
1621
any board where the devicetree has an I2C device node with compatible
17-
:dtcompatible:`issi,is31fl3194` enabled, along with the relevant bus
18-
controller node also being enabled.
22+
:dtcompatible:`issi,is31fl3194` long with the relevant bus controller
23+
node also being enabled.
24+
25+
likewise it can be build for an Arduino Giga with the Giga Display shield,
26+
or on and board where the devicetree has an I2C device with compatible
27+
:dtcompatible:`issi,is31fl3197` enabled along with the relevant bus controller
28+
node also being enabled.
1929

2030
.. zephyr-app-commands::
21-
:zephyr-app: samples/drivers/led/is31fl3194
31+
:zephyr-app: samples/drivers/led/is31fl319x
2232
:board: arduino_nicla_sense_me
2333
:goals: build flash
2434
:compact:
2535

36+
.. zephyr-app-commands::
37+
:zephyr-app: samples/drivers/led/is31fl319x
38+
:board: arduino_giga_r1//m7
39+
:shield: arduino_giga_display_shield
40+
:goals: build flash
41+
:compact:
42+
2643
After flashing, the LED starts to switch colors and messages with the current
2744
LED color are printed on the console. If a runtime error occurs, the sample
2845
exits without printing to the console.

0 commit comments

Comments
 (0)