21
21
#include <zephyr/dt-bindings/led/led.h>
22
22
23
23
LOG_MODULE_REGISTER (is31fl319x , CONFIG_LED_LOG_LEVEL );
24
+
25
+ /* define features that are specific subset of supported devices */
24
26
#define REG_NOT_DEFINED 0xff
25
27
28
+ #define FEATURE_ID_IS_ADDR 0x01 /* The id is the bus address */
29
+ #define FEATURE_SET_CURRENT 0x02 /* the device supports setting current limits */
30
+
26
31
struct is31f1319x_model {
32
+ const uint8_t features ;
27
33
const uint8_t prod_id_reg ;
28
34
const uint8_t shutdown_reg ;
29
35
const uint8_t conf_reg ;
@@ -38,7 +44,17 @@ struct is31f1319x_model {
38
44
const uint8_t led_channels [];
39
45
};
40
46
47
+ struct is31fl319x_config {
48
+ struct i2c_dt_spec bus ;
49
+ uint8_t channel_count ;
50
+ uint8_t num_leds ;
51
+ const struct led_info * led_infos ;
52
+ const uint8_t * current_limits ;
53
+ const struct is31f1319x_model * model ;
54
+ };
41
55
56
+ #ifdef CONFIG_DT_HAS_ISSI_IS31FL3194_ENABLED
57
+ /* IS31FL3194 model registers and values */
42
58
#define IS31FL3194_PROD_ID_REG 0x00
43
59
#define IS31FL3194_CONF_REG 0x01
44
60
#define IS31FL3194_CURRENT_REG 0x03
@@ -54,6 +70,8 @@ struct is31f1319x_model {
54
70
#define IS31FL3194_CHANNEL_COUNT 3
55
71
56
72
static const struct is31f1319x_model is31f13194_model = {
73
+ .features = FEATURE_SET_CURRENT ,
74
+
57
75
/* register indexes */
58
76
.prod_id_reg = IS31FL3194_PROD_ID_REG ,
59
77
.shutdown_reg = REG_NOT_DEFINED ,
@@ -69,15 +87,46 @@ static const struct is31f1319x_model is31f13194_model = {
69
87
70
88
/* channel output registers */
71
89
.led_channels = {IS31FL3194_OUT1_REG , IS31FL3194_OUT2_REG , IS31FL3194_OUT3_REG }};
90
+ #endif
72
91
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 ;
92
+ #ifdef CONFIG_DT_HAS_ISSI_IS31FL3197_ENABLED
93
+ /* IS31FL3197 model registers and values */
94
+ #define IS31FL3197_PROD_ID_REG 0x00
95
+ #define IS31FL3197_SHUTDOWN_REG 0x01
96
+ #define IS31FL3197_OPER_CONFIG_REG 0x02
97
+ #define IS31FL3197_OUT1_REG 0x10
98
+ #define IS31FL3197_OUT2_REG 0x11
99
+ #define IS31FL3197_OUT3_REG 0x12
100
+ #define IS31FL3197_OUT4_REG 0x13
101
+ #define IS31FL3197_UPDATE_REG 0x2b
102
+
103
+ #define IS31FL3197_SHUTDOWN_REG_VAL 0xf1 /* enable all channels */
104
+ #define IS31FL3197_OPER_CONFIG_REG_VAL 0xff /* set all to current level */
105
+ #define IS31FL3197_UPDATE_VAL 0xc5
106
+
107
+ #define IS31FL3197_CHANNEL_COUNT 4
108
+
109
+ static const struct is31f1319x_model is31f13197_model = {
110
+ .features = FEATURE_ID_IS_ADDR ,
111
+
112
+ /* register indexes */
113
+ .prod_id_reg = IS31FL3197_PROD_ID_REG ,
114
+ .shutdown_reg = IS31FL3197_SHUTDOWN_REG ,
115
+ .conf_reg = IS31FL3197_OPER_CONFIG_REG ,
116
+ .current_reg = REG_NOT_DEFINED ,
117
+ .update_reg = IS31FL3197_UPDATE_REG ,
118
+
119
+ /* values for those registers */
120
+ .prod_id_val = 0xff ,
121
+ .shutdown_reg_val = IS31FL3197_SHUTDOWN_REG_VAL ,
122
+ .conf_enable = IS31FL3197_OPER_CONFIG_REG_VAL ,
123
+ .update_val = IS31FL3197_UPDATE_VAL ,
124
+
125
+ /* channel output registers */
126
+ .led_channels = {IS31FL3197_OUT1_REG , IS31FL3197_OUT2_REG , IS31FL3197_OUT3_REG ,
127
+ IS31FL3197_OUT4_REG }
80
128
};
129
+ #endif
81
130
82
131
static const struct led_info * is31fl319x_led_to_info (const struct is31fl319x_config * config ,
83
132
uint32_t led )
@@ -123,15 +172,15 @@ static int is31fl319x_write_channels(const struct device *dev, uint32_t start_ch
123
172
uint32_t num_channels , const uint8_t * buf )
124
173
{
125
174
const struct is31fl319x_config * config = dev -> config ;
126
- const struct is31f1319x_model * regs = config -> regs ;
127
- int ret ;
175
+ const struct is31f1319x_model * model = config -> model ;
176
+ int ret = 0 ;
128
177
129
178
if ((start_channel + num_channels ) > config -> channel_count ) {
130
179
return - ENOTSUP ;
131
180
}
132
181
133
182
for (int i = 0 ; i < num_channels ; i ++ ) {
134
- ret = i2c_reg_write_byte_dt (& config -> bus , regs -> led_channels [i + start_channel ],
183
+ ret = i2c_reg_write_byte_dt (& config -> bus , model -> led_channels [i + start_channel ],
135
184
buf [i ]);
136
185
if (ret != 0 ) {
137
186
break ;
@@ -140,8 +189,8 @@ static int is31fl319x_write_channels(const struct device *dev, uint32_t start_ch
140
189
141
190
if (ret == 0 ) {
142
191
ret = i2c_reg_write_byte_dt (& config -> bus ,
143
- regs -> update_reg ,
144
- regs -> update_val );
192
+ model -> update_reg ,
193
+ model -> update_val );
145
194
}
146
195
147
196
if (ret != 0 ) {
@@ -174,7 +223,7 @@ static int is31fl319x_set_brightness(const struct device *dev, uint32_t led, uin
174
223
{
175
224
const struct is31fl319x_config * config = dev -> config ;
176
225
const struct led_info * info = is31fl319x_led_to_info (config , led );
177
- const struct is31f1319x_model * regs = config -> regs ;
226
+ const struct is31f1319x_model * model = config -> model ;
178
227
179
228
int ret = 0 ;
180
229
@@ -191,11 +240,11 @@ static int is31fl319x_set_brightness(const struct device *dev, uint32_t led, uin
191
240
192
241
uint8_t channel_start = is31fl319x_map_led_to_start_channel (config , led );
193
242
194
- ret = i2c_reg_write_byte_dt (& config -> bus , regs -> led_channels [channel_start ], value );
243
+ ret = i2c_reg_write_byte_dt (& config -> bus , model -> led_channels [channel_start ], value );
195
244
if (ret == 0 ) {
196
245
ret = i2c_reg_write_byte_dt (& config -> bus ,
197
- regs -> update_reg ,
198
- regs -> update_val );
246
+ model -> update_reg ,
247
+ model -> update_val );
199
248
}
200
249
201
250
if (ret != 0 ) {
@@ -210,10 +259,9 @@ static int is31fl319x_check_config(const struct device *dev)
210
259
const struct is31fl319x_config * config = dev -> config ;
211
260
const struct led_info * info ;
212
261
uint8_t rgb_count = 0 ;
213
- uint8_t i ;
214
262
215
263
/* verify that number of leds defined is not > number of channels */
216
- for (i = 0 ; i < config -> num_leds ; i ++ ) {
264
+ for (int i = 0 ; i < config -> num_leds ; i ++ ) {
217
265
info = & config -> led_infos [i ];
218
266
rgb_count += info -> num_colors ;
219
267
}
@@ -229,8 +277,8 @@ static int is31fl319x_init(const struct device *dev)
229
277
{
230
278
const struct is31fl319x_config * config = dev -> config ;
231
279
const struct led_info * info = NULL ;
232
- const struct is31f1319x_model * regs = config -> regs ;
233
- int i , j , ret ;
280
+ const struct is31f1319x_model * model = config -> model ;
281
+ int ret ;
234
282
uint8_t prod_id , band , channel ;
235
283
uint8_t current_reg = 0 ;
236
284
@@ -244,40 +292,59 @@ static int is31fl319x_init(const struct device *dev)
244
292
return - ENODEV ;
245
293
}
246
294
247
- ret = i2c_reg_read_byte_dt (& config -> bus , regs -> prod_id_reg , & prod_id );
295
+ ret = i2c_reg_read_byte_dt (& config -> bus , model -> prod_id_reg , & prod_id );
248
296
if (ret != 0 ) {
249
297
LOG_ERR ("%s: failed to read product ID" , dev -> name );
250
298
return ret ;
251
299
}
252
300
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 ;
301
+
302
+ if (model -> features & FEATURE_ID_IS_ADDR ) {
303
+ /* The product ID (8 bit) should be the I2C address(7 bit) */
304
+ if (prod_id != (config -> bus .addr << 1 )) {
305
+ LOG_ERR ("%s: invalid product ID 0x%02x (expected 0x%02x)" , dev -> name ,
306
+ prod_id , config -> bus .addr << 1 );
307
+ return - ENODEV ;
308
+ }
309
+ } else {
310
+ if (prod_id != model -> prod_id_val ) {
311
+ LOG_ERR ("%s: invalid product ID 0x%02x (expected 0x%02x)" , dev -> name ,
312
+ prod_id , model -> prod_id_val );
313
+ return - ENODEV ;
314
+ }
257
315
}
258
316
259
317
/* calc current limit register value */
260
- if (regs -> current_reg != REG_NOT_DEFINED ) {
318
+ if (model -> features & FEATURE_SET_CURRENT ) {
261
319
channel = 0 ;
262
- for (i = 0 ; i < config -> num_leds ; i ++ ) {
320
+ for (int i = 0 ; i < config -> num_leds ; i ++ ) {
263
321
info = & config -> led_infos [i ];
264
322
band = (config -> current_limits [i ] / 10 ) - 1 ;
265
323
266
- for (j = 0 ; j < info -> num_colors ; j ++ ) {
324
+ for (int j = 0 ; j < info -> num_colors ; j ++ ) {
267
325
current_reg |= band << (2 * channel );
268
326
channel ++ ;
269
327
}
270
328
}
271
329
272
- ret = i2c_reg_write_byte_dt (& config -> bus , regs -> current_reg , current_reg );
330
+ ret = i2c_reg_write_byte_dt (& config -> bus , model -> current_reg , current_reg );
331
+ if (ret != 0 ) {
332
+ LOG_ERR ("%s: failed to set current limit" , dev -> name );
333
+ return ret ;
334
+ }
335
+ }
336
+ if (model -> shutdown_reg != REG_NOT_DEFINED ) {
337
+ ret = i2c_reg_write_byte_dt (& config -> bus , model -> shutdown_reg ,
338
+ model -> shutdown_reg_val );
273
339
if (ret != 0 ) {
274
340
LOG_ERR ("%s: failed to set current limit" , dev -> name );
275
341
return ret ;
276
342
}
277
343
}
344
+
278
345
/* enable device */
279
- return i2c_reg_write_byte_dt (& config -> bus , regs -> conf_reg ,
280
- regs -> conf_enable );
346
+ return i2c_reg_write_byte_dt (& config -> bus , model -> conf_reg ,
347
+ model -> conf_enable );
281
348
}
282
349
283
350
static DEVICE_API (led , is31fl319x_led_api ) = {
@@ -301,7 +368,7 @@ static DEVICE_API(led, is31fl319x_led_api) = {
301
368
#define LED_CURRENT (led_node_id ) \
302
369
DT_PROP(led_node_id, current_limit),
303
370
304
- #define IS31FL319X_DEVICE (n , id , nchannels , pregs ) \
371
+ #define IS31FL319X_DEVICE (n , id , nchannels , pmodel ) \
305
372
\
306
373
DT_INST_FOREACH_CHILD(n, COLOR_MAPPING) \
307
374
\
@@ -319,13 +386,23 @@ static DEVICE_API(led, is31fl319x_led_api) = {
319
386
.num_leds = ARRAY_SIZE(is31fl319##id##_leds_##n), \
320
387
.led_infos = is31fl319##id##_leds_##n, \
321
388
.current_limits = is31fl319##id##_currents_##n, \
322
- .regs = pregs , \
389
+ .model = pmodel , \
323
390
}; \
324
391
DEVICE_DT_INST_DEFINE(n, &is31fl319x_init, NULL, NULL, \
325
392
&is31fl319##id##_config_##n, POST_KERNEL, \
326
393
CONFIG_LED_INIT_PRIORITY, &is31fl319x_led_api);
327
394
328
395
#undef DT_DRV_COMPAT
396
+ #ifdef CONFIG_DT_HAS_ISSI_IS31FL3194_ENABLED
329
397
#define DT_DRV_COMPAT issi_is31fl3194
330
398
DT_INST_FOREACH_STATUS_OKAY_VARGS (IS31FL319X_DEVICE , 4 , IS31FL3194_CHANNEL_COUNT ,
331
399
& is31f13194_model )
400
+ #endif
401
+
402
+ #ifdef CONFIG_DT_HAS_ISSI_IS31FL3197_ENABLED
403
+ #undef DT_DRV_COMPAT
404
+ #define DT_DRV_COMPAT issi_is31fl3197
405
+ DT_INST_FOREACH_STATUS_OKAY_VARGS (IS31FL319X_DEVICE , 7 , IS31FL3197_CHANNEL_COUNT ,
406
+ & is31f13197_model )
407
+ #endif
408
+ #undef DT_DRV_COMPAT
0 commit comments