@@ -147,14 +147,38 @@ struct wled {
147
147
u32 max_brightness ;
148
148
u32 short_count ;
149
149
u32 auto_detect_count ;
150
+ u32 version ;
150
151
bool disabled_by_short ;
151
152
bool has_short_detect ;
152
153
int short_irq ;
153
154
int ovp_irq ;
154
155
155
156
struct wled_config cfg ;
156
157
struct delayed_work ovp_work ;
158
+
159
+ /* Configures the brightness. Applicable for wled3, wled4 and wled5 */
157
160
int (* wled_set_brightness )(struct wled * wled , u16 brightness );
161
+
162
+ /* Configures the cabc register. Applicable for wled4 and wled5 */
163
+ int (* wled_cabc_config )(struct wled * wled , bool enable );
164
+
165
+ /*
166
+ * Toggles the sync bit for the brightness update to take place.
167
+ * Applicable for WLED3, WLED4 and WLED5.
168
+ */
169
+ int (* wled_sync_toggle )(struct wled * wled );
170
+
171
+ /*
172
+ * Time to wait before checking the OVP status after wled module enable.
173
+ * Applicable for WLED4 and WLED5.
174
+ */
175
+ int (* wled_ovp_delay )(struct wled * wled );
176
+
177
+ /*
178
+ * Determines if the auto string detection is required.
179
+ * Applicable for WLED4 and WLED5
180
+ */
181
+ bool (* wled_auto_detection_required )(struct wled * wled );
158
182
};
159
183
160
184
static int wled3_set_brightness (struct wled * wled , u16 brightness )
@@ -237,7 +261,7 @@ static int wled_module_enable(struct wled *wled, int val)
237
261
return 0 ;
238
262
}
239
263
240
- static int wled_sync_toggle (struct wled * wled )
264
+ static int wled3_sync_toggle (struct wled * wled )
241
265
{
242
266
int rc ;
243
267
unsigned int mask = GENMASK (wled -> max_string_count - 1 , 0 );
@@ -255,6 +279,46 @@ static int wled_sync_toggle(struct wled *wled)
255
279
return rc ;
256
280
}
257
281
282
+ static int wled_ovp_fault_status (struct wled * wled , bool * fault_set )
283
+ {
284
+ int rc ;
285
+ u32 int_rt_sts , fault_sts ;
286
+
287
+ * fault_set = false;
288
+ rc = regmap_read (wled -> regmap ,
289
+ wled -> ctrl_addr + WLED3_CTRL_REG_INT_RT_STS ,
290
+ & int_rt_sts );
291
+ if (rc < 0 ) {
292
+ dev_err (wled -> dev , "Failed to read INT_RT_STS rc=%d\n" , rc );
293
+ return rc ;
294
+ }
295
+
296
+ rc = regmap_read (wled -> regmap ,
297
+ wled -> ctrl_addr + WLED3_CTRL_REG_FAULT_STATUS ,
298
+ & fault_sts );
299
+ if (rc < 0 ) {
300
+ dev_err (wled -> dev , "Failed to read FAULT_STATUS rc=%d\n" , rc );
301
+ return rc ;
302
+ }
303
+
304
+ if (int_rt_sts & WLED3_CTRL_REG_OVP_FAULT_STATUS )
305
+ * fault_set = true;
306
+
307
+ if (fault_sts & WLED3_CTRL_REG_OVP_FAULT_BIT )
308
+ * fault_set = true;
309
+
310
+ if (* fault_set )
311
+ dev_dbg (wled -> dev , "WLED OVP fault detected, int_rt_sts=0x%x fault_sts=0x%x\n" ,
312
+ int_rt_sts , fault_sts );
313
+
314
+ return rc ;
315
+ }
316
+
317
+ static int wled4_ovp_delay (struct wled * wled )
318
+ {
319
+ return WLED_SOFT_START_DLY_US ;
320
+ }
321
+
258
322
static int wled_update_status (struct backlight_device * bl )
259
323
{
260
324
struct wled * wled = bl_get_data (bl );
@@ -275,7 +339,7 @@ static int wled_update_status(struct backlight_device *bl)
275
339
goto unlock_mutex ;
276
340
}
277
341
278
- rc = wled_sync_toggle (wled );
342
+ rc = wled -> wled_sync_toggle (wled );
279
343
if (rc < 0 ) {
280
344
dev_err (wled -> dev , "wled sync failed rc:%d\n" , rc );
281
345
goto unlock_mutex ;
@@ -298,6 +362,25 @@ static int wled_update_status(struct backlight_device *bl)
298
362
return rc ;
299
363
}
300
364
365
+ static int wled4_cabc_config (struct wled * wled , bool enable )
366
+ {
367
+ int i , j , rc ;
368
+ u8 val ;
369
+
370
+ for (i = 0 ; i < wled -> cfg .num_strings ; i ++ ) {
371
+ j = wled -> cfg .enabled_strings [i ];
372
+
373
+ val = enable ? WLED4_SINK_REG_STR_CABC_MASK : 0 ;
374
+ rc = regmap_update_bits (wled -> regmap , wled -> sink_addr +
375
+ WLED4_SINK_REG_STR_CABC (j ),
376
+ WLED4_SINK_REG_STR_CABC_MASK , val );
377
+ if (rc < 0 )
378
+ return rc ;
379
+ }
380
+
381
+ return 0 ;
382
+ }
383
+
301
384
#define WLED_SHORT_DLY_MS 20
302
385
#define WLED_SHORT_CNT_MAX 5
303
386
#define WLED_SHORT_RESET_CNT_DLY_US USEC_PER_SEC
@@ -345,9 +428,10 @@ static irqreturn_t wled_short_irq_handler(int irq, void *_wled)
345
428
346
429
static void wled_auto_string_detection (struct wled * wled )
347
430
{
348
- int rc = 0 , i ;
349
- u32 sink_config = 0 , int_sts ;
431
+ int rc = 0 , i , delay_time_us ;
432
+ u32 sink_config = 0 ;
350
433
u8 sink_test = 0 , sink_valid = 0 , val ;
434
+ bool fault_set ;
351
435
352
436
/* Read configured sink configuration */
353
437
rc = regmap_read (wled -> regmap , wled -> sink_addr +
@@ -376,14 +460,9 @@ static void wled_auto_string_detection(struct wled *wled)
376
460
}
377
461
378
462
if (wled -> cfg .cabc ) {
379
- for (i = 0 ; i < wled -> cfg .num_strings ; i ++ ) {
380
- rc = regmap_update_bits (wled -> regmap , wled -> sink_addr +
381
- WLED4_SINK_REG_STR_CABC (i ),
382
- WLED4_SINK_REG_STR_CABC_MASK ,
383
- 0 );
384
- if (rc < 0 )
385
- goto failed_detect ;
386
- }
463
+ rc = wled -> wled_cabc_config (wled , false);
464
+ if (rc < 0 )
465
+ goto failed_detect ;
387
466
}
388
467
389
468
/* Disable all sinks */
@@ -427,18 +506,17 @@ static void wled_auto_string_detection(struct wled *wled)
427
506
goto failed_detect ;
428
507
}
429
508
430
- usleep_range ( WLED_SOFT_START_DLY_US ,
431
- WLED_SOFT_START_DLY_US + 1000 );
509
+ delay_time_us = wled -> wled_ovp_delay ( wled );
510
+ usleep_range ( delay_time_us , delay_time_us + 1000 );
432
511
433
- rc = regmap_read (wled -> regmap , wled -> ctrl_addr +
434
- WLED3_CTRL_REG_INT_RT_STS , & int_sts );
512
+ rc = wled_ovp_fault_status (wled , & fault_set );
435
513
if (rc < 0 ) {
436
- dev_err (wled -> dev , "Error in reading WLED3_CTRL_INT_RT_STS rc=%d\n" ,
514
+ dev_err (wled -> dev , "Error in getting OVP fault_sts, rc=%d\n" ,
437
515
rc );
438
516
goto failed_detect ;
439
517
}
440
518
441
- if (int_sts & WLED3_CTRL_REG_OVP_FAULT_STATUS )
519
+ if (fault_set )
442
520
dev_dbg (wled -> dev , "WLED OVP fault detected with SINK %d\n" ,
443
521
i + 1 );
444
522
else
@@ -478,30 +556,30 @@ static void wled_auto_string_detection(struct wled *wled)
478
556
}
479
557
480
558
/* Enable valid sinks */
481
- for (i = 0 ; i < wled -> cfg .num_strings ; i ++ ) {
482
- if (wled -> cfg .cabc ) {
483
- rc = regmap_update_bits (wled -> regmap , wled -> sink_addr +
484
- WLED4_SINK_REG_STR_CABC (i ),
485
- WLED4_SINK_REG_STR_CABC_MASK ,
486
- WLED4_SINK_REG_STR_CABC_MASK );
487
- if (rc < 0 )
559
+ if (wled -> version == 4 ) {
560
+ for (i = 0 ; i < wled -> cfg .num_strings ; i ++ ) {
561
+ if (sink_config &
562
+ BIT (WLED4_SINK_REG_CURR_SINK_SHFT + i ))
563
+ val = WLED4_SINK_REG_STR_MOD_MASK ;
564
+ else
565
+ /* Disable modulator_en for unused sink */
566
+ val = 0 ;
567
+
568
+ rc = regmap_write (wled -> regmap , wled -> sink_addr +
569
+ WLED4_SINK_REG_STR_MOD_EN (i ), val );
570
+ if (rc < 0 ) {
571
+ dev_err (wled -> dev , "Failed to configure MODULATOR_EN rc=%d\n" ,
572
+ rc );
488
573
goto failed_detect ;
489
- }
490
-
491
- if (sink_config & BIT (WLED4_SINK_REG_CURR_SINK_SHFT + i ))
492
- val = WLED4_SINK_REG_STR_MOD_MASK ;
493
- else
494
- val = 0x0 ; /* Disable modulator_en for unused sink */
495
-
496
- rc = regmap_write (wled -> regmap , wled -> sink_addr +
497
- WLED4_SINK_REG_STR_MOD_EN (i ), val );
498
- if (rc < 0 ) {
499
- dev_err (wled -> dev , "Failed to configure MODULATOR_EN rc=%d\n" ,
500
- rc );
501
- goto failed_detect ;
574
+ }
502
575
}
503
576
}
504
577
578
+ /* Enable CABC */
579
+ rc = wled -> wled_cabc_config (wled , true);
580
+ if (rc < 0 )
581
+ goto failed_detect ;
582
+
505
583
/* Restore the feedback setting */
506
584
rc = regmap_write (wled -> regmap ,
507
585
wled -> ctrl_addr + WLED3_CTRL_REG_FEEDBACK_CONTROL , 0 );
@@ -534,7 +612,8 @@ static void wled_auto_string_detection(struct wled *wled)
534
612
535
613
#define WLED_AUTO_DETECT_OVP_COUNT 5
536
614
#define WLED_AUTO_DETECT_CNT_DLY_US USEC_PER_SEC
537
- static bool wled_auto_detection_required (struct wled * wled )
615
+
616
+ static bool wled4_auto_detection_required (struct wled * wled )
538
617
{
539
618
s64 elapsed_time_us ;
540
619
@@ -570,29 +649,19 @@ static bool wled_auto_detection_required(struct wled *wled)
570
649
static int wled_auto_detection_at_init (struct wled * wled )
571
650
{
572
651
int rc ;
573
- u32 fault_status , rt_status ;
652
+ bool fault_set ;
574
653
575
654
if (!wled -> cfg .auto_detection_enabled )
576
655
return 0 ;
577
656
578
- rc = regmap_read (wled -> regmap ,
579
- wled -> ctrl_addr + WLED3_CTRL_REG_INT_RT_STS ,
580
- & rt_status );
581
- if (rc < 0 ) {
582
- dev_err (wled -> dev , "Failed to read RT status rc=%d\n" , rc );
583
- return rc ;
584
- }
585
-
586
- rc = regmap_read (wled -> regmap ,
587
- wled -> ctrl_addr + WLED3_CTRL_REG_FAULT_STATUS ,
588
- & fault_status );
657
+ rc = wled_ovp_fault_status (wled , & fault_set );
589
658
if (rc < 0 ) {
590
- dev_err (wled -> dev , "Failed to read fault status rc=%d\n" , rc );
659
+ dev_err (wled -> dev , "Error in getting OVP fault_sts, rc=%d\n" ,
660
+ rc );
591
661
return rc ;
592
662
}
593
663
594
- if ((rt_status & WLED3_CTRL_REG_OVP_FAULT_STATUS ) ||
595
- (fault_status & WLED3_CTRL_REG_OVP_FAULT_BIT )) {
664
+ if (fault_set ) {
596
665
mutex_lock (& wled -> lock );
597
666
wled_auto_string_detection (wled );
598
667
mutex_unlock (& wled -> lock );
@@ -629,7 +698,7 @@ static irqreturn_t wled_ovp_irq_handler(int irq, void *_wled)
629
698
int_sts , fault_sts );
630
699
631
700
if (fault_sts & WLED3_CTRL_REG_OVP_FAULT_BIT ) {
632
- if (wled_auto_detection_required (wled )) {
701
+ if (wled -> wled_auto_detection_required (wled )) {
633
702
mutex_lock (& wled -> lock );
634
703
wled_auto_string_detection (wled );
635
704
mutex_unlock (& wled -> lock );
@@ -811,17 +880,12 @@ static int wled4_setup(struct wled *wled)
811
880
wled -> cfg .string_i_limit );
812
881
if (rc < 0 )
813
882
return rc ;
814
-
815
- addr = wled -> sink_addr +
816
- WLED4_SINK_REG_STR_CABC (j );
817
- rc = regmap_update_bits (wled -> regmap , addr ,
818
- WLED4_SINK_REG_STR_CABC_MASK ,
819
- wled -> cfg .cabc ?
820
- WLED4_SINK_REG_STR_CABC_MASK : 0 );
821
- if (rc < 0 )
822
- return rc ;
823
883
}
824
884
885
+ rc = wled4_cabc_config (wled , wled -> cfg .cabc );
886
+ if (rc < 0 )
887
+ return rc ;
888
+
825
889
rc = regmap_update_bits (wled -> regmap , wled -> ctrl_addr +
826
890
WLED3_CTRL_REG_MOD_EN ,
827
891
WLED3_CTRL_REG_MOD_EN_MASK ,
@@ -835,7 +899,7 @@ static int wled4_setup(struct wled *wled)
835
899
if (rc < 0 )
836
900
return rc ;
837
901
838
- rc = wled_sync_toggle (wled );
902
+ rc = wled -> wled_sync_toggle (wled );
839
903
if (rc < 0 ) {
840
904
dev_err (wled -> dev , "Failed to toggle sync reg rc:%d\n" , rc );
841
905
return rc ;
@@ -951,7 +1015,7 @@ static u32 wled_values(const struct wled_var_cfg *cfg, u32 idx)
951
1015
return idx ;
952
1016
}
953
1017
954
- static int wled_configure (struct wled * wled , int version )
1018
+ static int wled_configure (struct wled * wled )
955
1019
{
956
1020
struct wled_config * cfg = & wled -> cfg ;
957
1021
struct device * dev = wled -> dev ;
@@ -1035,12 +1099,13 @@ static int wled_configure(struct wled *wled, int version)
1035
1099
if (rc )
1036
1100
wled -> name = devm_kasprintf (dev , GFP_KERNEL , "%pOFn" , dev -> of_node );
1037
1101
1038
- switch (version ) {
1102
+ switch (wled -> version ) {
1039
1103
case 3 :
1040
1104
u32_opts = wled3_opts ;
1041
1105
size = ARRAY_SIZE (wled3_opts );
1042
1106
* cfg = wled3_config_defaults ;
1043
1107
wled -> wled_set_brightness = wled3_set_brightness ;
1108
+ wled -> wled_sync_toggle = wled3_sync_toggle ;
1044
1109
wled -> max_string_count = 3 ;
1045
1110
wled -> sink_addr = wled -> ctrl_addr ;
1046
1111
break ;
@@ -1050,6 +1115,11 @@ static int wled_configure(struct wled *wled, int version)
1050
1115
size = ARRAY_SIZE (wled4_opts );
1051
1116
* cfg = wled4_config_defaults ;
1052
1117
wled -> wled_set_brightness = wled4_set_brightness ;
1118
+ wled -> wled_sync_toggle = wled3_sync_toggle ;
1119
+ wled -> wled_cabc_config = wled4_cabc_config ;
1120
+ wled -> wled_ovp_delay = wled4_ovp_delay ;
1121
+ wled -> wled_auto_detection_required =
1122
+ wled4_auto_detection_required ;
1053
1123
wled -> max_string_count = 4 ;
1054
1124
1055
1125
prop_addr = of_get_address (dev -> of_node , 1 , NULL , NULL );
@@ -1186,7 +1256,6 @@ static int wled_probe(struct platform_device *pdev)
1186
1256
struct backlight_device * bl ;
1187
1257
struct wled * wled ;
1188
1258
struct regmap * regmap ;
1189
- int version ;
1190
1259
u32 val ;
1191
1260
int rc ;
1192
1261
@@ -1203,18 +1272,18 @@ static int wled_probe(struct platform_device *pdev)
1203
1272
wled -> regmap = regmap ;
1204
1273
wled -> dev = & pdev -> dev ;
1205
1274
1206
- version = (uintptr_t )of_device_get_match_data (& pdev -> dev );
1207
- if (!version ) {
1275
+ wled -> version = (uintptr_t )of_device_get_match_data (& pdev -> dev );
1276
+ if (!wled -> version ) {
1208
1277
dev_err (& pdev -> dev , "Unknown device version\n" );
1209
1278
return - ENODEV ;
1210
1279
}
1211
1280
1212
1281
mutex_init (& wled -> lock );
1213
- rc = wled_configure (wled , version );
1282
+ rc = wled_configure (wled );
1214
1283
if (rc )
1215
1284
return rc ;
1216
1285
1217
- switch (version ) {
1286
+ switch (wled -> version ) {
1218
1287
case 3 :
1219
1288
wled -> cfg .auto_detection_enabled = false;
1220
1289
rc = wled3_setup (wled );
0 commit comments