2121#include <zephyr/dt-bindings/led/led.h>
2222
2323LOG_MODULE_REGISTER (is31fl319x , CONFIG_LED_LOG_LEVEL );
24+
25+ /* define features that are specific subset of supported devices */
2426#define REG_NOT_DEFINED 0xff
2527
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+
2631struct is31f1319x_model {
32+ const uint8_t features ;
2733 const uint8_t prod_id_reg ;
2834 const uint8_t shutdown_reg ;
2935 const uint8_t conf_reg ;
@@ -38,7 +44,17 @@ struct is31f1319x_model {
3844 const uint8_t led_channels [];
3945};
4046
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+ };
4155
56+ #ifdef CONFIG_DT_HAS_ISSI_IS31FL3194_ENABLED
57+ /* IS31FL3194 model registers and values */
4258#define IS31FL3194_PROD_ID_REG 0x00
4359#define IS31FL3194_CONF_REG 0x01
4460#define IS31FL3194_CURRENT_REG 0x03
@@ -54,6 +70,8 @@ struct is31f1319x_model {
5470#define IS31FL3194_CHANNEL_COUNT 3
5571
5672static const struct is31f1319x_model is31f13194_model = {
73+ .features = FEATURE_SET_CURRENT ,
74+
5775 /* register indexes */
5876 .prod_id_reg = IS31FL3194_PROD_ID_REG ,
5977 .shutdown_reg = REG_NOT_DEFINED ,
@@ -69,15 +87,46 @@ static const struct is31f1319x_model is31f13194_model = {
6987
7088 /* channel output registers */
7189 .led_channels = {IS31FL3194_OUT1_REG , IS31FL3194_OUT2_REG , IS31FL3194_OUT3_REG }};
90+ #endif
7291
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 }
80128};
129+ #endif
81130
82131static const struct led_info * is31fl319x_led_to_info (const struct is31fl319x_config * config ,
83132 uint32_t led )
@@ -123,7 +172,7 @@ static int is31fl319x_write_channels(const struct device *dev, uint32_t start_ch
123172 uint32_t num_channels , const uint8_t * buf )
124173{
125174 const struct is31fl319x_config * config = dev -> config ;
126- const struct is31f1319x_model * regs = config -> regs ;
175+ const struct is31f1319x_model * model = config -> model ;
127176 int ret ;
128177 int i ;
129178
@@ -132,7 +181,7 @@ static int is31fl319x_write_channels(const struct device *dev, uint32_t start_ch
132181 }
133182
134183 for (i = 0 ; i < num_channels ; i ++ ) {
135- ret = i2c_reg_write_byte_dt (& config -> bus , regs -> led_channels [i + start_channel ],
184+ ret = i2c_reg_write_byte_dt (& config -> bus , model -> led_channels [i + start_channel ],
136185 buf [i ]);
137186 if (ret != 0 ) {
138187 break ;
@@ -141,8 +190,8 @@ static int is31fl319x_write_channels(const struct device *dev, uint32_t start_ch
141190
142191 if (ret == 0 ) {
143192 ret = i2c_reg_write_byte_dt (& config -> bus ,
144- regs -> update_reg ,
145- regs -> update_val );
193+ model -> update_reg ,
194+ model -> update_val );
146195 }
147196
148197 if (ret != 0 ) {
@@ -176,7 +225,7 @@ static int is31fl319x_set_brightness(const struct device *dev, uint32_t led, uin
176225{
177226 const struct is31fl319x_config * config = dev -> config ;
178227 const struct led_info * info = is31fl319x_led_to_info (config , led );
179- const struct is31f1319x_model * regs = config -> regs ;
228+ const struct is31f1319x_model * model = config -> model ;
180229 uint8_t channel_start ;
181230
182231 int ret = 0 ;
@@ -194,11 +243,11 @@ static int is31fl319x_set_brightness(const struct device *dev, uint32_t led, uin
194243
195244 channel_start = is31fl319x_map_led_to_start_channel (config , led );
196245
197- ret = i2c_reg_write_byte_dt (& config -> bus , regs -> led_channels [channel_start ], value );
246+ ret = i2c_reg_write_byte_dt (& config -> bus , model -> led_channels [channel_start ], value );
198247 if (ret == 0 ) {
199248 ret = i2c_reg_write_byte_dt (& config -> bus ,
200- regs -> update_reg ,
201- regs -> update_val );
249+ model -> update_reg ,
250+ model -> update_val );
202251 }
203252
204253 if (ret != 0 ) {
@@ -232,8 +281,8 @@ static int is31fl319x_init(const struct device *dev)
232281{
233282 const struct is31fl319x_config * config = dev -> config ;
234283 const struct led_info * info = NULL ;
235- const struct is31f1319x_model * regs = config -> regs ;
236- int i , j , ret ;
284+ const struct is31f1319x_model * model = config -> model ;
285+ int ret ;
237286 uint8_t prod_id , band , channel ;
238287 uint8_t current_reg = 0 ;
239288 int i , j ;
@@ -248,20 +297,30 @@ static int is31fl319x_init(const struct device *dev)
248297 return - ENODEV ;
249298 }
250299
251- ret = i2c_reg_read_byte_dt (& config -> bus , regs -> prod_id_reg , & prod_id );
300+ ret = i2c_reg_read_byte_dt (& config -> bus , model -> prod_id_reg , & prod_id );
252301 if (ret != 0 ) {
253302 LOG_ERR ("%s: failed to read product ID" , dev -> name );
254303 return ret ;
255304 }
256305
257- if (prod_id != regs -> prod_id_val ) {
258- LOG_ERR ("%s: invalid product ID 0x%02x (expected 0x%02x)" , dev -> name , prod_id ,
259- regs -> prod_id_val );
260- return - ENODEV ;
306+
307+ if (model -> features & FEATURE_ID_IS_ADDR ) {
308+ /* The product ID (8 bit) should be the I2C address(7 bit) */
309+ if (prod_id != (config -> bus .addr << 1 )) {
310+ LOG_ERR ("%s: invalid product ID 0x%02x (expected 0x%02x)" , dev -> name ,
311+ prod_id , config -> bus .addr << 1 );
312+ return - ENODEV ;
313+ }
314+ } else {
315+ if (prod_id != model -> prod_id_val ) {
316+ LOG_ERR ("%s: invalid product ID 0x%02x (expected 0x%02x)" , dev -> name ,
317+ prod_id , model -> prod_id_val );
318+ return - ENODEV ;
319+ }
261320 }
262321
263322 /* calc current limit register value */
264- if (regs -> current_reg != REG_NOT_DEFINED ) {
323+ if (model -> features & FEATURE_SET_CURRENT ) {
265324 channel = 0 ;
266325 for (i = 0 ; i < config -> num_leds ; i ++ ) {
267326 info = & config -> led_infos [i ];
@@ -273,15 +332,24 @@ static int is31fl319x_init(const struct device *dev)
273332 }
274333 }
275334
276- ret = i2c_reg_write_byte_dt (& config -> bus , regs -> current_reg , current_reg );
335+ ret = i2c_reg_write_byte_dt (& config -> bus , model -> current_reg , current_reg );
277336 if (ret != 0 ) {
278337 LOG_ERR ("%s: failed to set current limit" , dev -> name );
279338 return ret ;
280339 }
281340 }
341+ if (model -> shutdown_reg != REG_NOT_DEFINED ) {
342+ ret = i2c_reg_write_byte_dt (& config -> bus , model -> shutdown_reg ,
343+ model -> shutdown_reg_val );
344+ if (ret != 0 ) {
345+ LOG_ERR ("%s: failed to set current limit" , dev -> name );
346+ return ret ;
347+ }
348+ }
349+
282350 /* enable device */
283- return i2c_reg_write_byte_dt (& config -> bus , regs -> conf_reg ,
284- regs -> conf_enable );
351+ return i2c_reg_write_byte_dt (& config -> bus , model -> conf_reg ,
352+ model -> conf_enable );
285353}
286354
287355static DEVICE_API (led , is31fl319x_led_api ) = {
@@ -305,7 +373,7 @@ static DEVICE_API(led, is31fl319x_led_api) = {
305373#define LED_CURRENT (led_node_id ) \
306374 DT_PROP(led_node_id, current_limit),
307375
308- #define IS31FL319X_DEVICE (n , id , nchannels , pregs ) \
376+ #define IS31FL319X_DEVICE (n , id , nchannels , pmodel ) \
309377 \
310378 DT_INST_FOREACH_CHILD(n, COLOR_MAPPING) \
311379 \
@@ -323,12 +391,21 @@ static DEVICE_API(led, is31fl319x_led_api) = {
323391 .num_leds = ARRAY_SIZE(is31fl319##id##_leds_##n), \
324392 .led_infos = is31fl319##id##_leds_##n, \
325393 .current_limits = is31fl319##id##_currents_##n, \
326- .regs = pregs, \
394+ .model = pmodel, \
327395 }; \
328396 DEVICE_DT_INST_DEFINE(n, &is31fl319x_init, NULL, NULL, \
329397 &is31fl319##id##_config_##n, POST_KERNEL, \
330398 CONFIG_LED_INIT_PRIORITY, &is31fl319x_led_api);
331399
400+ #ifdef CONFIG_DT_HAS_ISSI_IS31FL3194_ENABLED
332401#define DT_DRV_COMPAT issi_is31fl3194
333402DT_INST_FOREACH_STATUS_OKAY_VARGS (IS31FL319X_DEVICE , 4 , IS31FL3194_CHANNEL_COUNT ,
334403 & is31f13194_model )
404+ #endif
405+
406+ #ifdef CONFIG_DT_HAS_ISSI_IS31FL3197_ENABLED
407+ #undef DT_DRV_COMPAT
408+ #define DT_DRV_COMPAT issi_is31fl3197
409+ DT_INST_FOREACH_STATUS_OKAY_VARGS (IS31FL319X_DEVICE , 7 , IS31FL3197_CHANNEL_COUNT ,
410+ & is31f13197_model )
411+ #endif
0 commit comments