@@ -104,45 +104,36 @@ static int is31fl319x_get_info(const struct device *dev,
104104 return 0 ;
105105}
106106
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 )
109124{
110125 const struct is31fl319x_config * config = dev -> config ;
111- const struct led_info * info = is31fl319x_led_to_info (config , led );
112126 const struct is31f1319x_model * regs = config -> regs ;
113127 int ret ;
128+ int i ;
114129
115- if (info == NULL ) {
116- return - ENODEV ;
117- }
118-
119- if (info -> num_colors > config -> channel_count ) {
130+ if ((start_channel + num_channels ) > config -> channel_count ) {
120131 return - ENOTSUP ;
121132 }
122133
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 );
134+ for (i = 0 ; i < num_channels ; i ++ ) {
135+ ret = i2c_reg_write_byte_dt (& config -> bus , regs -> led_channels [i + start_channel ],
136+ buf [i ]);
146137 if (ret != 0 ) {
147138 break ;
148139 }
@@ -161,11 +152,32 @@ static int is31fl319x_set_color(const struct device *dev, uint32_t led, uint8_t
161152 return ret ;
162153}
163154
155+ static int is31fl319x_set_color (const struct device * dev , uint32_t led , uint8_t num_colors ,
156+ const uint8_t * color )
157+ {
158+ const struct is31fl319x_config * config = dev -> config ;
159+ const struct led_info * info = is31fl319x_led_to_info (config , led );
160+ uint8_t channel_start ;
161+
162+ if (info == NULL ) {
163+ return - ENODEV ;
164+ }
165+
166+ channel_start = is31fl319x_map_led_to_start_channel (config , led );
167+
168+ if (info -> num_colors > config -> channel_count ) {
169+ return - ENOTSUP ;
170+ }
171+
172+ return is31fl319x_write_channels (dev , channel_start , num_colors , color );
173+ }
174+
164175static int is31fl319x_set_brightness (const struct device * dev , uint32_t led , uint8_t value )
165176{
166177 const struct is31fl319x_config * config = dev -> config ;
167178 const struct led_info * info = is31fl319x_led_to_info (config , led );
168179 const struct is31f1319x_model * regs = config -> regs ;
180+ uint8_t channel_start ;
169181
170182 int ret = 0 ;
171183
@@ -180,7 +192,9 @@ static int is31fl319x_set_brightness(const struct device *dev, uint32_t led, uin
180192 /* Rescale 0..100 to 0..255 */
181193 value = value * 255 / LED_BRIGHTNESS_MAX ;
182194
183- ret = i2c_reg_write_byte_dt (& config -> bus , regs -> led_channels [led ], value );
195+ channel_start = is31fl319x_map_led_to_start_channel (config , led );
196+
197+ ret = i2c_reg_write_byte_dt (& config -> bus , regs -> led_channels [channel_start ], value );
184198 if (ret == 0 ) {
185199 ret = i2c_reg_write_byte_dt (& config -> bus ,
186200 regs -> update_reg ,
@@ -194,81 +208,20 @@ static int is31fl319x_set_brightness(const struct device *dev, uint32_t led, uin
194208 return ret ;
195209}
196210
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-
226211static int is31fl319x_check_config (const struct device * dev )
227212{
228213 const struct is31fl319x_config * config = dev -> config ;
229214 const struct led_info * info ;
230- uint8_t rgb_counts [ 3 ] = { 0 } ;
215+ uint8_t rgb_count = 0 ;
231216 uint8_t i ;
232217
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- }
218+ /* verify that number of leds defined is not > number of channels */
219+ for (i = 0 ; i < config -> num_leds ; i ++ ) {
220+ info = & config -> led_infos [i ];
221+ rgb_count += info -> num_colors ;
222+ }
263223
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 );
224+ if (rgb_count > config -> channel_count ) {
272225 return - EINVAL ;
273226 }
274227
@@ -280,9 +233,10 @@ static int is31fl319x_init(const struct device *dev)
280233 const struct is31fl319x_config * config = dev -> config ;
281234 const struct led_info * info = NULL ;
282235 const struct is31f1319x_model * regs = config -> regs ;
283- int i , ret ;
284- uint8_t prod_id , band ;
236+ int i , j , ret ;
237+ uint8_t prod_id , band , channel ;
285238 uint8_t current_reg = 0 ;
239+ int i , j ;
286240
287241 ret = is31fl319x_check_config (dev );
288242 if (ret != 0 ) {
@@ -307,27 +261,24 @@ static int is31fl319x_init(const struct device *dev)
307261 }
308262
309263 /* 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 */
264+ if (regs -> current_reg != REG_NOT_DEFINED ) {
265+ channel = 0 ;
319266 for (i = 0 ; i < config -> num_leds ; i ++ ) {
267+ info = & config -> led_infos [i ];
320268 band = (config -> current_limits [i ] / 10 ) - 1 ;
321- current_reg |= band << (2 * i );
269+
270+ for (j = 0 ; j < info -> num_colors ; j ++ ) {
271+ current_reg |= band << (2 * channel );
272+ channel ++ ;
273+ }
322274 }
323- }
324275
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 ;
276+ ret = i2c_reg_write_byte_dt (& config -> bus , regs -> current_reg , current_reg );
277+ if (ret != 0 ) {
278+ LOG_ERR ("%s: failed to set current limit" , dev -> name );
279+ return ret ;
280+ }
329281 }
330-
331282 /* enable device */
332283 return i2c_reg_write_byte_dt (& config -> bus , regs -> conf_reg ,
333284 regs -> conf_enable );
@@ -337,6 +288,7 @@ static DEVICE_API(led, is31fl319x_led_api) = {
337288 .set_brightness = is31fl319x_set_brightness ,
338289 .get_info = is31fl319x_get_info ,
339290 .set_color = is31fl319x_set_color ,
291+ .write_channels = is31fl319x_write_channels ,
340292};
341293
342294#define COLOR_MAPPING (led_node_id ) \
@@ -377,7 +329,6 @@ static DEVICE_API(led, is31fl319x_led_api) = {
377329 &is31fl319##id##_config_##n, POST_KERNEL, \
378330 CONFIG_LED_INIT_PRIORITY, &is31fl319x_led_api);
379331
380- #undef DT_DRV_COMPAT
381332#define DT_DRV_COMPAT issi_is31fl3194
382333DT_INST_FOREACH_STATUS_OKAY_VARGS (IS31FL319X_DEVICE , 4 , IS31FL3194_CHANNEL_COUNT ,
383334 & is31f13194_model )
0 commit comments