@@ -104,45 +104,35 @@ static int is31fl319x_get_info(const struct device *dev,
104
104
return 0 ;
105
105
}
106
106
107
- static int is31fl319x_set_color (const struct device * dev , uint32_t led , uint8_t num_colors ,
108
- const uint8_t * color )
107
+ static uint8_t is31fl319x_map_led_to_start_channel (const struct is31fl319x_config * config ,
108
+ uint32_t led )
109
+ {
110
+ /* It is assumed that led has been validated before calling this */
111
+ const struct led_info * info = config -> led_infos ;
112
+ uint8_t channel = 0 ;
113
+
114
+ while (led ) {
115
+ channel += info -> num_colors ;
116
+ led -- ;
117
+ info ++ ;
118
+ }
119
+ return channel ;
120
+ }
121
+
122
+ static int is31fl319x_write_channels (const struct device * dev , uint32_t start_channel ,
123
+ uint32_t num_channels , const uint8_t * buf )
109
124
{
110
125
const struct is31fl319x_config * config = dev -> config ;
111
- const struct led_info * info = is31fl319x_led_to_info (config , led );
112
126
const struct is31f1319x_model * regs = config -> regs ;
113
127
int ret ;
114
128
115
- if (info == NULL ) {
116
- return - ENODEV ;
117
- }
118
-
119
- if (info -> num_colors > config -> channel_count ) {
129
+ if ((start_channel + num_channels ) > config -> channel_count ) {
120
130
return - ENOTSUP ;
121
131
}
122
132
123
- if (num_colors > config -> channel_count ) {
124
- return - ENOTSUP ;
125
- }
126
-
127
- for (int i = 0 ; i < num_colors ; i ++ ) {
128
- uint8_t value ;
129
-
130
- switch (info -> color_mapping [i ]) {
131
- case LED_COLOR_ID_RED :
132
- value = color [0 ];
133
- break ;
134
- case LED_COLOR_ID_GREEN :
135
- value = color [1 ];
136
- break ;
137
- case LED_COLOR_ID_BLUE :
138
- value = color [2 ];
139
- break ;
140
- default :
141
- /* unreachable: mapping already tested in is31fl319x_check_config */
142
- return - EINVAL ;
143
- }
144
-
145
- ret = i2c_reg_write_byte_dt (& config -> bus , regs -> led_channels [i ], value );
133
+ for (int i = 0 ; i < num_channels ; i ++ ) {
134
+ ret = i2c_reg_write_byte_dt (& config -> bus , regs -> led_channels [i + start_channel ],
135
+ buf [i ]);
146
136
if (ret != 0 ) {
147
137
break ;
148
138
}
@@ -161,6 +151,25 @@ static int is31fl319x_set_color(const struct device *dev, uint32_t led, uint8_t
161
151
return ret ;
162
152
}
163
153
154
+ static int is31fl319x_set_color (const struct device * dev , uint32_t led , uint8_t num_colors ,
155
+ const uint8_t * color )
156
+ {
157
+ const struct is31fl319x_config * config = dev -> config ;
158
+ const struct led_info * info = is31fl319x_led_to_info (config , led );
159
+
160
+ if (info == NULL ) {
161
+ return - ENODEV ;
162
+ }
163
+
164
+ uint8_t channel_start = is31fl319x_map_led_to_start_channel (config , led );
165
+
166
+ if (info -> num_colors > config -> channel_count ) {
167
+ return - ENOTSUP ;
168
+ }
169
+
170
+ return is31fl319x_write_channels (dev , channel_start , num_colors , color );
171
+ }
172
+
164
173
static int is31fl319x_set_brightness (const struct device * dev , uint32_t led , uint8_t value )
165
174
{
166
175
const struct is31fl319x_config * config = dev -> config ;
@@ -180,7 +189,9 @@ static int is31fl319x_set_brightness(const struct device *dev, uint32_t led, uin
180
189
/* Rescale 0..100 to 0..255 */
181
190
value = value * 255 / LED_BRIGHTNESS_MAX ;
182
191
183
- ret = i2c_reg_write_byte_dt (& config -> bus , regs -> led_channels [led ], value );
192
+ uint8_t channel_start = is31fl319x_map_led_to_start_channel (config , led );
193
+
194
+ ret = i2c_reg_write_byte_dt (& config -> bus , regs -> led_channels [channel_start ], value );
184
195
if (ret == 0 ) {
185
196
ret = i2c_reg_write_byte_dt (& config -> bus ,
186
197
regs -> update_reg ,
@@ -194,81 +205,20 @@ static int is31fl319x_set_brightness(const struct device *dev, uint32_t led, uin
194
205
return ret ;
195
206
}
196
207
197
- /*
198
- * Counts red, green, blue channels; returns true if color_id is valid
199
- * and no more than one channel maps to the same color
200
- */
201
- static bool is31fl319x_count_colors (const struct device * dev ,
202
- uint8_t color_id , uint8_t * rgb_counts )
203
- {
204
- bool ret = false;
205
-
206
- switch (color_id ) {
207
- case LED_COLOR_ID_RED :
208
- ret = (++ rgb_counts [0 ] == 1 );
209
- break ;
210
- case LED_COLOR_ID_GREEN :
211
- ret = (++ rgb_counts [1 ] == 1 );
212
- break ;
213
- case LED_COLOR_ID_BLUE :
214
- ret = (++ rgb_counts [2 ] == 1 );
215
- break ;
216
- }
217
-
218
- if (!ret ) {
219
- LOG_ERR ("%s: invalid color %d (duplicate or not RGB)" ,
220
- dev -> name , color_id );
221
- }
222
-
223
- return ret ;
224
- }
225
-
226
208
static int is31fl319x_check_config (const struct device * dev )
227
209
{
228
210
const struct is31fl319x_config * config = dev -> config ;
229
211
const struct led_info * info ;
230
- uint8_t rgb_counts [ 3 ] = { 0 } ;
212
+ uint8_t rgb_count = 0 ;
231
213
uint8_t i ;
232
214
233
- switch (config -> num_leds ) {
234
- case 1 :
235
- /* check that it is a three-channel LED */
236
- info = & config -> led_infos [0 ];
237
-
238
- if (info -> num_colors != 3 ) {
239
- LOG_ERR ("%s: invalid number of colors %d "
240
- "(must be 3 for RGB LED)" ,
241
- dev -> name , info -> num_colors );
242
- return - EINVAL ;
243
- }
244
-
245
- for (i = 0 ; i < 3 ; i ++ ) {
246
- if (!is31fl319x_count_colors (dev , info -> color_mapping [i ], rgb_counts )) {
247
- return - EINVAL ;
248
- }
249
-
250
- }
251
- break ;
252
- case 3 :
253
- /* check that each LED is single-color */
254
- for (i = 0 ; i < 3 ; i ++ ) {
255
- info = & config -> led_infos [i ];
256
-
257
- if (info -> num_colors != 1 ) {
258
- LOG_ERR ("%s: invalid number of colors %d "
259
- "(must be 1 when defining multiple LEDs)" ,
260
- dev -> name , info -> num_colors );
261
- return - EINVAL ;
262
- }
215
+ /* verify that number of leds defined is not > number of channels */
216
+ for (i = 0 ; i < config -> num_leds ; i ++ ) {
217
+ info = & config -> led_infos [i ];
218
+ rgb_count += info -> num_colors ;
219
+ }
263
220
264
- if (!is31fl319x_count_colors (dev , info -> color_mapping [0 ], rgb_counts )) {
265
- return - EINVAL ;
266
- }
267
- }
268
- break ;
269
- default :
270
- LOG_ERR ("%s: invalid number of LEDs %d (must be 1 or 3)" ,
271
- dev -> name , config -> num_leds );
221
+ if (rgb_count > config -> channel_count ) {
272
222
return - EINVAL ;
273
223
}
274
224
@@ -280,8 +230,8 @@ static int is31fl319x_init(const struct device *dev)
280
230
const struct is31fl319x_config * config = dev -> config ;
281
231
const struct led_info * info = NULL ;
282
232
const struct is31f1319x_model * regs = config -> regs ;
283
- int i , ret ;
284
- uint8_t prod_id , band ;
233
+ int i , j , ret ;
234
+ uint8_t prod_id , band , channel ;
285
235
uint8_t current_reg = 0 ;
286
236
287
237
ret = is31fl319x_check_config (dev );
@@ -307,27 +257,24 @@ static int is31fl319x_init(const struct device *dev)
307
257
}
308
258
309
259
/* calc current limit register value */
310
- info = & config -> led_infos [0 ];
311
- if (info -> num_colors == IS31FL3194_CHANNEL_COUNT ) {
312
- /* one RGB LED: set all channels to the same current limit */
313
- band = (config -> current_limits [0 ] / 10 ) - 1 ;
314
- for (i = 0 ; i < IS31FL3194_CHANNEL_COUNT ; i ++ ) {
315
- current_reg |= band << (2 * i );
316
- }
317
- } else {
318
- /* single-channel LEDs: independent limits */
260
+ if (regs -> current_reg != REG_NOT_DEFINED ) {
261
+ channel = 0 ;
319
262
for (i = 0 ; i < config -> num_leds ; i ++ ) {
263
+ info = & config -> led_infos [i ];
320
264
band = (config -> current_limits [i ] / 10 ) - 1 ;
321
- current_reg |= band << (2 * i );
265
+
266
+ for (j = 0 ; j < info -> num_colors ; j ++ ) {
267
+ current_reg |= band << (2 * channel );
268
+ channel ++ ;
269
+ }
322
270
}
323
- }
324
271
325
- ret = i2c_reg_write_byte_dt (& config -> bus , IS31FL3194_CURRENT_REG , current_reg );
326
- if (ret != 0 ) {
327
- LOG_ERR ("%s: failed to set current limit" , dev -> name );
328
- return ret ;
272
+ ret = i2c_reg_write_byte_dt (& config -> bus , regs -> current_reg , current_reg );
273
+ if (ret != 0 ) {
274
+ LOG_ERR ("%s: failed to set current limit" , dev -> name );
275
+ return ret ;
276
+ }
329
277
}
330
-
331
278
/* enable device */
332
279
return i2c_reg_write_byte_dt (& config -> bus , regs -> conf_reg ,
333
280
regs -> conf_enable );
@@ -337,6 +284,7 @@ static DEVICE_API(led, is31fl319x_led_api) = {
337
284
.set_brightness = is31fl319x_set_brightness ,
338
285
.get_info = is31fl319x_get_info ,
339
286
.set_color = is31fl319x_set_color ,
287
+ .write_channels = is31fl319x_write_channels ,
340
288
};
341
289
342
290
#define COLOR_MAPPING (led_node_id ) \
0 commit comments