1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2024 Christian Marangi <ansuelsmth@gmail.com>
6 #include <linux/bitfield.h>
7 #include <linux/cleanup.h>
8 #include <linux/delay.h>
9 #include <linux/firmware.h>
10 #include <linux/i2c.h>
11 #include <linux/iopoll.h>
12 #include <linux/leds.h>
13 #include <linux/module.h>
14 #include <linux/mutex.h>
16 #include <linux/platform_data/leds-lp55xx.h>
17 #include <linux/slab.h>
18 #include <dt-bindings/leds/leds-lp55xx.h>
20 #include "leds-lp55xx-common.h"
22 #define LP5569_MAX_LEDS 9
24 /* Memory is used like this:
25 * 0x00 engine 1 program (4 pages)
26 * 0x40 engine 2 program (4 pages)
27 * 0x80 engine 3 program (4 pages)
28 * 0xc0 engine 1 muxing info (1 page)
29 * 0xd0 engine 2 muxing info (1 page)
30 * 0xe0 engine 3 muxing info (1 page)
32 #define LP5569_PAGES_PER_ENGINE 4
34 #define LP5569_REG_ENABLE 0x00
35 #define LP5569_ENABLE BIT(6)
37 #define LP5569_REG_EXEC_CTRL 0x01
38 #define LP5569_MODE_ENG_SHIFT 2
40 #define LP5569_REG_OP_MODE 0x02
41 #define LP5569_EXEC_ENG_SHIFT 2
43 #define LP5569_REG_ENABLE_LEDS_MSB 0x04
44 #define LP5569_REG_ENABLE_LEDS_LSB 0x05
45 #define LP5569_REG_LED_CTRL_BASE 0x07
46 #define LP5569_FADER_MAPPING_MASK GENMASK(7, 5)
47 #define LP5569_REG_LED_PWM_BASE 0x16
48 #define LP5569_REG_LED_CURRENT_BASE 0x22
49 #define LP5569_REG_MISC 0x2F
50 #define LP5569_AUTO_INC BIT(6)
51 #define LP5569_PWR_SAVE BIT(5)
52 #define LP5569_CP_MODE_MASK GENMASK(4, 3)
53 #define LP5569_PWM_PWR_SAVE BIT(2)
54 #define LP5569_INTERNAL_CLK BIT(0)
55 #define LP5569_REG_MISC2 0x33
56 #define LP5569_LED_SHORT_TEST BIT(4)
57 #define LP5569_LED_OPEN_TEST BIT(3)
58 #define LP5569_REG_STATUS 0x3C
59 #define LP5569_MASK_BUSY BIT(7)
60 #define LP5569_STARTUP_BUSY BIT(6)
61 #define LP5569_ENGINE_BUSY BIT(5)
62 #define LP5569_ENGINE1_INT BIT(2)
63 #define LP5569_ENGINE2_INT BIT(1)
64 #define LP5569_ENGINE3_INT BIT(0)
65 #define LP5569_ENG_STATUS_MASK (LP5569_ENGINE1_INT | LP5569_ENGINE2_INT | \
67 #define LP5569_REG_IO_CONTROL 0x3D
68 #define LP5569_CLK_OUTPUT BIT(3)
69 #define LP5569_REG_RESET 0x3F
70 #define LP5569_RESET 0xFF
71 #define LP5569_REG_MASTER_FADER_BASE 0x46
72 #define LP5569_REG_CH1_PROG_START 0x4B
73 #define LP5569_REG_CH2_PROG_START 0x4C
74 #define LP5569_REG_CH3_PROG_START 0x4D
75 #define LP5569_REG_PROG_PAGE_SEL 0x4F
76 #define LP5569_REG_PROG_MEM 0x50
77 #define LP5569_REG_LED_FAULT1 0x81
78 #define LP5569_LED_FAULT8 BIT(0)
79 #define LP5569_REG_LED_FAULT2 0x82
80 #define LP5569_LED_FAULT7 BIT(7)
81 #define LP5569_LED_FAULT6 BIT(6)
82 #define LP5569_LED_FAULT5 BIT(5)
83 #define LP5569_LED_FAULT4 BIT(4)
84 #define LP5569_LED_FAULT3 BIT(3)
85 #define LP5569_LED_FAULT2 BIT(2)
86 #define LP5569_LED_FAULT1 BIT(1)
87 #define LP5569_LED_FAULT0 BIT(0)
89 #define LP5569_ENG1_PROG_ADDR 0x0
90 #define LP5569_ENG2_PROG_ADDR 0x40
91 #define LP5569_ENG3_PROG_ADDR 0x80
92 #define LP5569_ENG1_MUX_ADDR 0xc0
93 #define LP5569_ENG2_MUX_ADDR 0xd0
94 #define LP5569_ENG3_MUX_ADDR 0xe0
96 #define LP5569_STARTUP_SLEEP 500
98 #define LEDn_STATUS_FAULT(n, status) ((status) >> (n) & BIT(0))
100 #define LP5569_DEFAULT_CONFIG \
101 (LP5569_AUTO_INC | LP5569_PWR_SAVE | LP5569_PWM_PWR_SAVE)
103 static void lp5569_run_engine(struct lp55xx_chip
*chip
, bool start
)
106 lp55xx_stop_engine(chip
);
107 lp55xx_turn_off_channels(chip
);
111 lp55xx_run_engine_common(chip
);
114 static int lp5569_init_program_engine(struct lp55xx_chip
*chip
)
120 /* Precompiled pattern per ENGINE setting LED MUX start and stop addresses */
121 static const u8 pattern
[][LP55xx_BYTES_PER_PAGE
] = {
122 { 0x9c, LP5569_ENG1_MUX_ADDR
, 0x9c, 0xb0, 0x9d, 0x80, 0xd8, 0x00, 0},
123 { 0x9c, LP5569_ENG2_MUX_ADDR
, 0x9c, 0xc0, 0x9d, 0x80, 0xd8, 0x00, 0},
124 { 0x9c, LP5569_ENG3_MUX_ADDR
, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0},
127 /* Setup each ENGINE program start address */
128 ret
= lp55xx_write(chip
, LP5569_REG_CH1_PROG_START
, LP5569_ENG1_PROG_ADDR
);
132 ret
= lp55xx_write(chip
, LP5569_REG_CH2_PROG_START
, LP5569_ENG2_PROG_ADDR
);
136 ret
= lp55xx_write(chip
, LP5569_REG_CH3_PROG_START
, LP5569_ENG3_PROG_ADDR
);
140 /* Write precompiled pattern for LED MUX address space for each ENGINE */
141 for (i
= LP55XX_ENGINE_1
; i
<= LP55XX_ENGINE_3
; i
++) {
142 chip
->engine_idx
= i
;
143 lp55xx_load_engine(chip
);
145 for (j
= 0; j
< LP55xx_BYTES_PER_PAGE
; j
++) {
146 ret
= lp55xx_write(chip
, LP5569_REG_PROG_MEM
+ j
,
153 lp5569_run_engine(chip
, true);
155 /* Let the programs run for couple of ms and check the engine status */
156 usleep_range(3000, 6000);
157 lp55xx_read(chip
, LP5569_REG_STATUS
, &status
);
158 status
= FIELD_GET(LP5569_ENG_STATUS_MASK
, status
);
160 if (status
!= LP5569_ENG_STATUS_MASK
) {
161 dev_err(&chip
->cl
->dev
,
162 "could not configure LED engine, status = 0x%.2x\n",
168 lp55xx_stop_all_engine(chip
);
172 static int lp5569_post_init_device(struct lp55xx_chip
*chip
)
177 val
= LP5569_DEFAULT_CONFIG
;
178 val
|= FIELD_PREP(LP5569_CP_MODE_MASK
, chip
->pdata
->charge_pump_mode
);
179 ret
= lp55xx_write(chip
, LP5569_REG_MISC
, val
);
183 if (chip
->pdata
->clock_mode
== LP55XX_CLOCK_INT
) {
184 /* Internal clock MUST be configured before CLK output */
185 ret
= lp55xx_update_bits(chip
, LP5569_REG_MISC
,
187 LP5569_INTERNAL_CLK
);
191 ret
= lp55xx_update_bits(chip
, LP5569_REG_IO_CONTROL
,
198 ret
= lp55xx_write(chip
, LP5569_REG_ENABLE
, LP5569_ENABLE
);
202 read_poll_timeout(lp55xx_read
, ret
, !(val
& LP5569_STARTUP_BUSY
),
203 LP5569_STARTUP_SLEEP
, LP5569_STARTUP_SLEEP
* 10, false,
204 chip
, LP5569_REG_STATUS
, &val
);
206 return lp5569_init_program_engine(chip
);
209 static ssize_t
lp5569_led_open_test(struct lp55xx_led
*led
, char *buf
)
211 struct lp55xx_chip
*chip
= led
->chip
;
212 struct lp55xx_platform_data
*pdata
= chip
->pdata
;
213 bool leds_fault
[LP5569_MAX_LEDS
];
214 struct lp55xx_led
*led_tmp
= led
;
218 /* Set in STANDBY state */
219 ret
= lp55xx_write(chip
, LP5569_REG_ENABLE
, 0);
223 /* Wait 1ms for device to enter STANDBY state */
224 usleep_range(1000, 2000);
226 /* Set Charge Pump to 1.5x */
227 ret
= lp55xx_update_bits(chip
, LP5569_REG_MISC
,
228 FIELD_PREP(LP5569_CP_MODE_MASK
, LP55XX_CP_BOOST
),
229 LP5569_CP_MODE_MASK
);
233 /* Enable LED Open Test */
234 ret
= lp55xx_update_bits(chip
, LP5569_REG_MISC2
, LP5569_LED_OPEN_TEST
,
235 LP5569_LED_OPEN_TEST
);
239 /* Put Device in NORMAL state */
240 ret
= lp55xx_write(chip
, LP5569_REG_ENABLE
, LP5569_ENABLE
);
244 /* Wait 500 us for device to enter NORMAL state */
245 usleep_range(500, 750);
247 /* Enable LED and set to 100% brightness */
248 for (i
= 0; i
< pdata
->num_channels
; i
++) {
249 ret
= lp55xx_write(chip
, LP5569_REG_LED_PWM_BASE
+ led_tmp
->chan_nr
,
257 /* Wait 500 us for device to fill status regs */
258 usleep_range(500, 750);
260 /* Parse status led fault 1 regs */
261 ret
= lp55xx_read(chip
, LP5569_REG_LED_FAULT1
, &status
);
265 for (i
= 0; i
< 8; i
++)
266 leds_fault
[i
] = !!((status
>> i
) & 0x1);
268 /* Parse status led fault 2 regs */
269 ret
= lp55xx_read(chip
, LP5569_REG_LED_FAULT2
, &status
);
273 for (i
= 0; i
< 1; i
++)
274 leds_fault
[i
+ 8] = !!((status
>> i
) & 0x1);
276 /* Report LED fault */
278 for (i
= 0; i
< pdata
->num_channels
; i
++) {
279 if (leds_fault
[led_tmp
->chan_nr
])
280 pos
+= sysfs_emit_at(buf
, pos
, "LED %d OPEN FAIL\n",
289 /* Disable LED Open Test */
290 lp55xx_update_bits(chip
, LP5569_REG_MISC2
, LP5569_LED_OPEN_TEST
, 0);
293 for (i
= 0; i
< pdata
->num_channels
; i
++) {
294 lp55xx_write(chip
, LP5569_REG_LED_PWM_BASE
+ led_tmp
->chan_nr
, 0);
302 static ssize_t
lp5569_led_short_test(struct lp55xx_led
*led
, char *buf
)
304 struct lp55xx_chip
*chip
= led
->chip
;
305 struct lp55xx_platform_data
*pdata
= chip
->pdata
;
306 bool leds_fault
[LP5569_MAX_LEDS
];
307 struct lp55xx_led
*led_tmp
= led
;
311 /* Set in STANDBY state */
312 ret
= lp55xx_write(chip
, LP5569_REG_ENABLE
, 0);
316 /* Wait 1ms for device to enter STANDBY state */
317 usleep_range(1000, 2000);
319 /* Set Charge Pump to 1x */
320 ret
= lp55xx_update_bits(chip
, LP5569_REG_MISC
,
321 FIELD_PREP(LP5569_CP_MODE_MASK
, LP55XX_CP_BYPASS
),
322 LP5569_CP_MODE_MASK
);
326 /* Enable LED and set to 100% brightness and current to 100% (25.5mA) */
327 for (i
= 0; i
< pdata
->num_channels
; i
++) {
328 ret
= lp55xx_write(chip
, LP5569_REG_LED_PWM_BASE
+ led_tmp
->chan_nr
,
333 ret
= lp55xx_write(chip
, LP5569_REG_LED_CURRENT_BASE
+ led_tmp
->chan_nr
,
341 /* Put Device in NORMAL state */
342 ret
= lp55xx_write(chip
, LP5569_REG_ENABLE
, LP5569_ENABLE
);
346 /* Wait 500 us for device to enter NORMAL state */
347 usleep_range(500, 750);
349 /* Enable LED Shorted Test */
350 ret
= lp55xx_update_bits(chip
, LP5569_REG_MISC2
, LP5569_LED_OPEN_TEST
,
351 LP5569_LED_SHORT_TEST
);
355 /* Wait 500 us for device to fill status regs */
356 usleep_range(500, 750);
358 /* Parse status led fault 1 regs */
359 ret
= lp55xx_read(chip
, LP5569_REG_LED_FAULT1
, &status
);
363 for (i
= 0; i
< 8; i
++)
364 leds_fault
[i
] = !!LEDn_STATUS_FAULT(i
, status
);
366 /* Parse status led fault 2 regs */
367 ret
= lp55xx_read(chip
, LP5569_REG_LED_FAULT2
, &status
);
371 for (i
= 0; i
< 1; i
++)
372 leds_fault
[i
+ 8] = !!LEDn_STATUS_FAULT(i
, status
);
374 /* Report LED fault */
376 for (i
= 0; i
< pdata
->num_channels
; i
++) {
377 if (leds_fault
[led_tmp
->chan_nr
])
378 pos
+= sysfs_emit_at(buf
, pos
, "LED %d SHORTED FAIL\n",
387 /* Disable LED Shorted Test */
388 lp55xx_update_bits(chip
, LP5569_REG_MISC2
, LP5569_LED_SHORT_TEST
, 0);
391 for (i
= 0; i
< pdata
->num_channels
; i
++) {
392 lp55xx_write(chip
, LP5569_REG_LED_PWM_BASE
+ led_tmp
->chan_nr
, 0);
400 static ssize_t
lp5569_selftest(struct device
*dev
,
401 struct device_attribute
*attr
,
404 struct lp55xx_led
*led
= i2c_get_clientdata(to_i2c_client(dev
));
405 struct lp55xx_chip
*chip
= led
->chip
;
408 guard(mutex
)(&chip
->lock
);
411 pos
= lp5569_led_open_test(led
, buf
);
413 return sprintf(buf
, "FAIL\n");
415 /* Test LED Shorted */
416 pos
+= lp5569_led_short_test(led
, buf
);
418 return sprintf(buf
, "FAIL\n");
420 for (i
= 0; i
< chip
->pdata
->num_channels
; i
++) {
421 /* Restore current */
422 lp55xx_write(chip
, LP5569_REG_LED_CURRENT_BASE
+ led
->chan_nr
,
425 /* Restore brightness */
426 lp55xx_write(chip
, LP5569_REG_LED_PWM_BASE
+ led
->chan_nr
,
431 return pos
== 0 ? sysfs_emit(buf
, "OK\n") : pos
;
434 LP55XX_DEV_ATTR_ENGINE_MODE(1);
435 LP55XX_DEV_ATTR_ENGINE_MODE(2);
436 LP55XX_DEV_ATTR_ENGINE_MODE(3);
437 LP55XX_DEV_ATTR_ENGINE_LEDS(1);
438 LP55XX_DEV_ATTR_ENGINE_LEDS(2);
439 LP55XX_DEV_ATTR_ENGINE_LEDS(3);
440 LP55XX_DEV_ATTR_ENGINE_LOAD(1);
441 LP55XX_DEV_ATTR_ENGINE_LOAD(2);
442 LP55XX_DEV_ATTR_ENGINE_LOAD(3);
443 static LP55XX_DEV_ATTR_RO(selftest
, lp5569_selftest
);
444 LP55XX_DEV_ATTR_MASTER_FADER(1);
445 LP55XX_DEV_ATTR_MASTER_FADER(2);
446 LP55XX_DEV_ATTR_MASTER_FADER(3);
447 static LP55XX_DEV_ATTR_RW(master_fader_leds
, lp55xx_show_master_fader_leds
,
448 lp55xx_store_master_fader_leds
);
450 static struct attribute
*lp5569_attributes
[] = {
451 &dev_attr_engine1_mode
.attr
,
452 &dev_attr_engine2_mode
.attr
,
453 &dev_attr_engine3_mode
.attr
,
454 &dev_attr_engine1_load
.attr
,
455 &dev_attr_engine2_load
.attr
,
456 &dev_attr_engine3_load
.attr
,
457 &dev_attr_engine1_leds
.attr
,
458 &dev_attr_engine2_leds
.attr
,
459 &dev_attr_engine3_leds
.attr
,
460 &dev_attr_selftest
.attr
,
461 &dev_attr_master_fader1
.attr
,
462 &dev_attr_master_fader2
.attr
,
463 &dev_attr_master_fader3
.attr
,
464 &dev_attr_master_fader_leds
.attr
,
468 static const struct attribute_group lp5569_group
= {
469 .attrs
= lp5569_attributes
,
472 /* Chip specific configurations */
473 static struct lp55xx_device_config lp5569_cfg
= {
475 .addr
= LP5569_REG_OP_MODE
,
476 .shift
= LP5569_MODE_ENG_SHIFT
,
479 .addr
= LP5569_REG_EXEC_CTRL
,
480 .shift
= LP5569_EXEC_ENG_SHIFT
,
483 .addr
= LP5569_REG_RESET
,
487 .addr
= LP5569_REG_ENABLE
,
488 .val
= LP5569_ENABLE
,
491 .addr
= LP5569_REG_PROG_MEM
,
493 .reg_led_pwm_base
= {
494 .addr
= LP5569_REG_LED_PWM_BASE
,
496 .reg_led_current_base
= {
497 .addr
= LP5569_REG_LED_CURRENT_BASE
,
499 .reg_master_fader_base
= {
500 .addr
= LP5569_REG_MASTER_FADER_BASE
,
502 .reg_led_ctrl_base
= {
503 .addr
= LP5569_REG_LED_CTRL_BASE
,
505 .pages_per_engine
= LP5569_PAGES_PER_ENGINE
,
506 .max_channel
= LP5569_MAX_LEDS
,
507 .post_init_device
= lp5569_post_init_device
,
508 .brightness_fn
= lp55xx_led_brightness
,
509 .multicolor_brightness_fn
= lp55xx_multicolor_brightness
,
510 .set_led_current
= lp55xx_set_led_current
,
511 .firmware_cb
= lp55xx_firmware_loaded_cb
,
512 .run_engine
= lp5569_run_engine
,
513 .dev_attr_group
= &lp5569_group
,
516 static const struct i2c_device_id lp5569_id
[] = {
517 { "lp5569", .driver_data
= (kernel_ulong_t
)&lp5569_cfg
, },
521 MODULE_DEVICE_TABLE(i2c
, lp5569_id
);
523 static const struct of_device_id of_lp5569_leds_match
[] = {
524 { .compatible
= "ti,lp5569", .data
= &lp5569_cfg
, },
528 MODULE_DEVICE_TABLE(of
, of_lp5569_leds_match
);
530 static struct i2c_driver lp5569_driver
= {
533 .of_match_table
= of_lp5569_leds_match
,
535 .probe
= lp55xx_probe
,
536 .remove
= lp55xx_remove
,
537 .id_table
= lp5569_id
,
540 module_i2c_driver(lp5569_driver
);
542 MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
543 MODULE_DESCRIPTION("LP5569 LED engine");
544 MODULE_LICENSE("GPL");