]> Git Repo - J-linux.git/blob - drivers/leds/leds-lp5569.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / leds / leds-lp5569.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2024 Christian Marangi <[email protected]>
4  */
5
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>
15 #include <linux/of.h>
16 #include <linux/platform_data/leds-lp55xx.h>
17 #include <linux/slab.h>
18 #include <dt-bindings/leds/leds-lp55xx.h>
19
20 #include "leds-lp55xx-common.h"
21
22 #define LP5569_MAX_LEDS                 9
23
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)
31  */
32 #define LP5569_PAGES_PER_ENGINE         4
33
34 #define LP5569_REG_ENABLE               0x00
35 #define   LP5569_ENABLE                 BIT(6)
36
37 #define LP5569_REG_EXEC_CTRL            0x01
38 #define   LP5569_MODE_ENG_SHIFT         2
39
40 #define LP5569_REG_OP_MODE              0x02
41 #define   LP5569_EXEC_ENG_SHIFT         2
42
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 | \
66                                          LP5569_ENGINE3_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)
88
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
95
96 #define LP5569_STARTUP_SLEEP            500
97
98 #define LEDn_STATUS_FAULT(n, status)    ((status) >> (n) & BIT(0))
99
100 #define LP5569_DEFAULT_CONFIG \
101         (LP5569_AUTO_INC | LP5569_PWR_SAVE | LP5569_PWM_PWR_SAVE)
102
103 static void lp5569_run_engine(struct lp55xx_chip *chip, bool start)
104 {
105         if (!start) {
106                 lp55xx_stop_engine(chip);
107                 lp55xx_turn_off_channels(chip);
108                 return;
109         }
110
111         lp55xx_run_engine_common(chip);
112 }
113
114 static int lp5569_init_program_engine(struct lp55xx_chip *chip)
115 {
116         int i;
117         int j;
118         int ret;
119         u8 status;
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},
125         };
126
127         /* Setup each ENGINE program start address */
128         ret = lp55xx_write(chip, LP5569_REG_CH1_PROG_START, LP5569_ENG1_PROG_ADDR);
129         if (ret)
130                 return ret;
131
132         ret = lp55xx_write(chip, LP5569_REG_CH2_PROG_START, LP5569_ENG2_PROG_ADDR);
133         if (ret)
134                 return ret;
135
136         ret = lp55xx_write(chip, LP5569_REG_CH3_PROG_START, LP5569_ENG3_PROG_ADDR);
137         if (ret)
138                 return ret;
139
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);
144
145                 for (j = 0; j < LP55xx_BYTES_PER_PAGE; j++) {
146                         ret = lp55xx_write(chip, LP5569_REG_PROG_MEM + j,
147                                            pattern[i - 1][j]);
148                         if (ret)
149                                 goto out;
150                 }
151         }
152
153         lp5569_run_engine(chip, true);
154
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);
159
160         if (status != LP5569_ENG_STATUS_MASK) {
161                 dev_err(&chip->cl->dev,
162                         "could not configure LED engine, status = 0x%.2x\n",
163                         status);
164                 ret = -EINVAL;
165         }
166
167 out:
168         lp55xx_stop_all_engine(chip);
169         return ret;
170 }
171
172 static int lp5569_post_init_device(struct lp55xx_chip *chip)
173 {
174         int ret;
175         u8 val;
176
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);
180         if (ret)
181                 return ret;
182
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,
186                                          LP5569_INTERNAL_CLK,
187                                          LP5569_INTERNAL_CLK);
188                 if (ret)
189                         return ret;
190
191                 ret = lp55xx_update_bits(chip, LP5569_REG_IO_CONTROL,
192                                          LP5569_CLK_OUTPUT,
193                                          LP5569_CLK_OUTPUT);
194                 if (ret)
195                         return ret;
196         }
197
198         ret = lp55xx_write(chip, LP5569_REG_ENABLE, LP5569_ENABLE);
199         if (ret)
200                 return ret;
201
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);
205
206         return lp5569_init_program_engine(chip);
207 }
208
209 static ssize_t lp5569_led_open_test(struct lp55xx_led *led, char *buf)
210 {
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;
215         int i, ret, pos = 0;
216         u8 status;
217
218         /* Set in STANDBY state */
219         ret = lp55xx_write(chip, LP5569_REG_ENABLE, 0);
220         if (ret)
221                 goto exit;
222
223         /* Wait 1ms for device to enter STANDBY state */
224         usleep_range(1000, 2000);
225
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);
230         if (ret)
231                 goto exit;
232
233         /* Enable LED Open Test */
234         ret = lp55xx_update_bits(chip, LP5569_REG_MISC2, LP5569_LED_OPEN_TEST,
235                                  LP5569_LED_OPEN_TEST);
236         if (ret)
237                 goto exit;
238
239         /* Put Device in NORMAL state */
240         ret = lp55xx_write(chip, LP5569_REG_ENABLE, LP5569_ENABLE);
241         if (ret)
242                 goto exit;
243
244         /* Wait 500 us for device to enter NORMAL state */
245         usleep_range(500, 750);
246
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,
250                                    LED_FULL);
251                 if (ret)
252                         goto exit;
253
254                 led_tmp++;
255         }
256
257         /* Wait 500 us for device to fill status regs */
258         usleep_range(500, 750);
259
260         /* Parse status led fault 1 regs */
261         ret = lp55xx_read(chip, LP5569_REG_LED_FAULT1, &status);
262         if (ret < 0)
263                 goto exit;
264
265         for (i = 0; i < 8; i++)
266                 leds_fault[i] = !!((status >> i) & 0x1);
267
268         /* Parse status led fault 2 regs */
269         ret = lp55xx_read(chip, LP5569_REG_LED_FAULT2, &status);
270         if (ret < 0)
271                 goto exit;
272
273         for (i = 0; i < 1; i++)
274                 leds_fault[i + 8] = !!((status >> i) & 0x1);
275
276         /* Report LED fault */
277         led_tmp = led;
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",
281                                              led_tmp->chan_nr);
282
283                 led_tmp++;
284         }
285
286         ret = pos;
287
288 exit:
289         /* Disable LED Open Test */
290         lp55xx_update_bits(chip, LP5569_REG_MISC2, LP5569_LED_OPEN_TEST, 0);
291
292         led_tmp = led;
293         for (i = 0; i < pdata->num_channels; i++) {
294                 lp55xx_write(chip, LP5569_REG_LED_PWM_BASE + led_tmp->chan_nr, 0);
295
296                 led_tmp++;
297         }
298
299         return ret;
300 }
301
302 static ssize_t lp5569_led_short_test(struct lp55xx_led *led, char *buf)
303 {
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;
308         int i, ret, pos = 0;
309         u8 status;
310
311         /* Set in STANDBY state */
312         ret = lp55xx_write(chip, LP5569_REG_ENABLE, 0);
313         if (ret)
314                 goto exit;
315
316         /* Wait 1ms for device to enter STANDBY state */
317         usleep_range(1000, 2000);
318
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);
323         if (ret)
324                 goto exit;
325
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,
329                                    LED_FULL);
330                 if (ret)
331                         goto exit;
332
333                 ret = lp55xx_write(chip, LP5569_REG_LED_CURRENT_BASE + led_tmp->chan_nr,
334                                    LED_FULL);
335                 if (ret)
336                         goto exit;
337
338                 led_tmp++;
339         }
340
341         /* Put Device in NORMAL state */
342         ret = lp55xx_write(chip, LP5569_REG_ENABLE, LP5569_ENABLE);
343         if (ret)
344                 goto exit;
345
346         /* Wait 500 us for device to enter NORMAL state */
347         usleep_range(500, 750);
348
349         /* Enable LED Shorted Test */
350         ret = lp55xx_update_bits(chip, LP5569_REG_MISC2, LP5569_LED_OPEN_TEST,
351                                  LP5569_LED_SHORT_TEST);
352         if (ret)
353                 goto exit;
354
355         /* Wait 500 us for device to fill status regs */
356         usleep_range(500, 750);
357
358         /* Parse status led fault 1 regs */
359         ret = lp55xx_read(chip, LP5569_REG_LED_FAULT1, &status);
360         if (ret < 0)
361                 goto exit;
362
363         for (i = 0; i < 8; i++)
364                 leds_fault[i] = !!LEDn_STATUS_FAULT(i, status);
365
366         /* Parse status led fault 2 regs */
367         ret = lp55xx_read(chip, LP5569_REG_LED_FAULT2, &status);
368         if (ret < 0)
369                 goto exit;
370
371         for (i = 0; i < 1; i++)
372                 leds_fault[i + 8] = !!LEDn_STATUS_FAULT(i, status);
373
374         /* Report LED fault */
375         led_tmp = led;
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",
379                                              led_tmp->chan_nr);
380
381                 led_tmp++;
382         }
383
384         ret = pos;
385
386 exit:
387         /* Disable LED Shorted Test */
388         lp55xx_update_bits(chip, LP5569_REG_MISC2, LP5569_LED_SHORT_TEST, 0);
389
390         led_tmp = led;
391         for (i = 0; i < pdata->num_channels; i++) {
392                 lp55xx_write(chip, LP5569_REG_LED_PWM_BASE + led_tmp->chan_nr, 0);
393
394                 led_tmp++;
395         }
396
397         return ret;
398 }
399
400 static ssize_t lp5569_selftest(struct device *dev,
401                                struct device_attribute *attr,
402                                char *buf)
403 {
404         struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
405         struct lp55xx_chip *chip = led->chip;
406         int i, pos = 0;
407
408         guard(mutex)(&chip->lock);
409
410         /* Test LED Open */
411         pos = lp5569_led_open_test(led, buf);
412         if (pos < 0)
413                 return sprintf(buf, "FAIL\n");
414
415         /* Test LED Shorted */
416         pos += lp5569_led_short_test(led, buf);
417         if (pos < 0)
418                 return sprintf(buf, "FAIL\n");
419
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,
423                              led->led_current);
424
425                 /* Restore brightness */
426                 lp55xx_write(chip, LP5569_REG_LED_PWM_BASE + led->chan_nr,
427                              led->brightness);
428                 led++;
429         }
430
431         return pos == 0 ? sysfs_emit(buf, "OK\n") : pos;
432 }
433
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);
449
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,
465         NULL,
466 };
467
468 static const struct attribute_group lp5569_group = {
469         .attrs = lp5569_attributes,
470 };
471
472 /* Chip specific configurations */
473 static struct lp55xx_device_config lp5569_cfg = {
474         .reg_op_mode = {
475                 .addr = LP5569_REG_OP_MODE,
476                 .shift = LP5569_MODE_ENG_SHIFT,
477         },
478         .reg_exec = {
479                 .addr = LP5569_REG_EXEC_CTRL,
480                 .shift = LP5569_EXEC_ENG_SHIFT,
481         },
482         .reset = {
483                 .addr = LP5569_REG_RESET,
484                 .val  = LP5569_RESET,
485         },
486         .enable = {
487                 .addr = LP5569_REG_ENABLE,
488                 .val  = LP5569_ENABLE,
489         },
490         .prog_mem_base = {
491                 .addr = LP5569_REG_PROG_MEM,
492         },
493         .reg_led_pwm_base = {
494                 .addr = LP5569_REG_LED_PWM_BASE,
495         },
496         .reg_led_current_base = {
497                 .addr = LP5569_REG_LED_CURRENT_BASE,
498         },
499         .reg_master_fader_base = {
500                 .addr = LP5569_REG_MASTER_FADER_BASE,
501         },
502         .reg_led_ctrl_base = {
503                 .addr = LP5569_REG_LED_CTRL_BASE,
504         },
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,
514 };
515
516 static const struct i2c_device_id lp5569_id[] = {
517         { "lp5569",  .driver_data = (kernel_ulong_t)&lp5569_cfg, },
518         { }
519 };
520
521 MODULE_DEVICE_TABLE(i2c, lp5569_id);
522
523 static const struct of_device_id of_lp5569_leds_match[] = {
524         { .compatible = "ti,lp5569", .data = &lp5569_cfg, },
525         {},
526 };
527
528 MODULE_DEVICE_TABLE(of, of_lp5569_leds_match);
529
530 static struct i2c_driver lp5569_driver = {
531         .driver = {
532                 .name   = "lp5569",
533                 .of_match_table = of_lp5569_leds_match,
534         },
535         .probe          = lp55xx_probe,
536         .remove         = lp55xx_remove,
537         .id_table       = lp5569_id,
538 };
539
540 module_i2c_driver(lp5569_driver);
541
542 MODULE_AUTHOR("Christian Marangi <[email protected]>");
543 MODULE_DESCRIPTION("LP5569 LED engine");
544 MODULE_LICENSE("GPL");
This page took 0.057379 seconds and 4 git commands to generate.