Skip to content

Commit a121069

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: to also check for is31fl3197 boards Signed-off-by: Kurt Eckhardt <[email protected]>
1 parent 42d293e commit a121069

File tree

7 files changed

+177
-27
lines changed

7 files changed

+177
-27
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.

samples/drivers/led/is31fl319x/README.rst

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,15 @@ Building and Running
2525

2626
This sample can be built and executed on an Arduino Nicla Sense ME, or on
2727
any board where the devicetree has an I2C device node with compatible
28-
:dtcompatible:`issi,is31fl3194` enabled, along with the relevant bus
29-
controller node also being enabled.
28+
:dtcompatible:`issi,is31fl3194` or :dtcompatible:`issi,is31fl319` with the
29+
relevant bus controller node also being enabled.
3030

3131
.. zephyr-app-commands::
3232
:zephyr-app: samples/drivers/led/is31fl319x
3333
:board: arduino_nicla_sense_me
3434
:goals: build flash
3535
:compact:
3636

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

samples/drivers/led/is31fl319x/src/main.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ static const struct color_data color_sequence[] = {
3131
};
3232

3333
/*
34-
* A build error on this line means your board is unsupported.
34+
* A build error on these lines means your board is unsupported.
3535
*/
3636
#ifdef CONFIG_IS31FL3194
3737
const struct device *led = DEVICE_DT_GET_ANY(issi_is31fl3194);
38+
#elif defined(CONFIG_IS31FL3197)
39+
const struct device *led = DEVICE_DT_GET_ANY(issi_is31fl3197);
3840
#endif
3941

4042
uint8_t rgb_mapping[3] = {0, 0, 0}; /* R G B */

0 commit comments

Comments
 (0)