GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / leds / rgb / leds-ktd202x.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Kinetic KTD2026/7 RGB/White LED driver with I2C interface
4  *
5  * Copyright 2023 AndrĂ© Apitzsch <git@apitzsch.eu>
6  *
7  * Datasheet: https://www.kinet-ic.com/uploads/KTD2026-7-04h.pdf
8  */
9
10 #include <linux/i2c.h>
11 #include <linux/led-class-multicolor.h>
12 #include <linux/module.h>
13 #include <linux/mutex.h>
14 #include <linux/of.h>
15 #include <linux/of_device.h>
16 #include <linux/regmap.h>
17 #include <linux/regulator/consumer.h>
18
19 #define KTD2026_NUM_LEDS 3
20 #define KTD2027_NUM_LEDS 4
21 #define KTD202X_MAX_LEDS 4
22
23 /* Register bank */
24 #define KTD202X_REG_RESET_CONTROL       0x00
25 #define KTD202X_REG_FLASH_PERIOD        0x01
26 #define KTD202X_REG_PWM1_TIMER          0x02
27 #define KTD202X_REG_PWM2_TIMER          0x03
28 #define KTD202X_REG_CHANNEL_CTRL        0x04
29 #define KTD202X_REG_TRISE_FALL          0x05
30 #define KTD202X_REG_LED_IOUT(x)         (0x06 + (x))
31
32 /* Register 0 */
33 #define KTD202X_TIMER_SLOT_CONTROL_TSLOT1       0x00
34 #define KTD202X_TIMER_SLOT_CONTROL_TSLOT2       0x01
35 #define KTD202X_TIMER_SLOT_CONTROL_TSLOT3       0x02
36 #define KTD202X_TIMER_SLOT_CONTROL_TSLOT4       0x03
37 #define KTD202X_RSTR_RESET                      0x07
38
39 #define KTD202X_ENABLE_CTRL_WAKE        0x00 /* SCL High & SDA High */
40 #define KTD202X_ENABLE_CTRL_SLEEP       0x08 /* SCL High & SDA Toggling */
41
42 #define KTD202X_TRISE_FALL_SCALE_NORMAL         0x00
43 #define KTD202X_TRISE_FALL_SCALE_SLOW_X2        0x20
44 #define KTD202X_TRISE_FALL_SCALE_SLOW_X4        0x40
45 #define KTD202X_TRISE_FALL_SCALE_FAST_X8        0x60
46
47 /* Register 1 */
48 #define KTD202X_FLASH_PERIOD_256_MS_LOG_RAMP    0x00
49
50 /* Register 2-3 */
51 #define KTD202X_FLASH_ON_TIME_0_4_PERCENT       0x01
52
53 /* Register 4 */
54 #define KTD202X_CHANNEL_CTRL_MASK(x) (BIT(2 * (x)) | BIT(2 * (x) + 1))
55 #define KTD202X_CHANNEL_CTRL_OFF 0x00
56 #define KTD202X_CHANNEL_CTRL_ON(x) BIT(2 * (x))
57 #define KTD202X_CHANNEL_CTRL_PWM1(x) BIT(2 * (x) + 1)
58 #define KTD202X_CHANNEL_CTRL_PWM2(x) (BIT(2 * (x)) | BIT(2 * (x) + 1))
59
60 /* Register 5 */
61 #define KTD202X_RAMP_TIMES_2_MS                 0x00
62
63 /* Register 6-9 */
64 #define KTD202X_LED_CURRENT_10_mA               0x4f
65
66 #define KTD202X_FLASH_PERIOD_MIN_MS 256
67 #define KTD202X_FLASH_PERIOD_STEP_MS 128
68 #define KTD202X_FLASH_PERIOD_MAX_STEPS 126
69 #define KTD202X_FLASH_ON_MAX 256
70
71 #define KTD202X_MAX_BRIGHTNESS 192
72
73 static const struct reg_default ktd202x_reg_defaults[] = {
74         { KTD202X_REG_RESET_CONTROL, KTD202X_TIMER_SLOT_CONTROL_TSLOT1 |
75                 KTD202X_ENABLE_CTRL_WAKE | KTD202X_TRISE_FALL_SCALE_NORMAL },
76         { KTD202X_REG_FLASH_PERIOD, KTD202X_FLASH_PERIOD_256_MS_LOG_RAMP },
77         { KTD202X_REG_PWM1_TIMER, KTD202X_FLASH_ON_TIME_0_4_PERCENT },
78         { KTD202X_REG_PWM2_TIMER, KTD202X_FLASH_ON_TIME_0_4_PERCENT },
79         { KTD202X_REG_CHANNEL_CTRL, KTD202X_CHANNEL_CTRL_OFF },
80         { KTD202X_REG_TRISE_FALL, KTD202X_RAMP_TIMES_2_MS },
81         { KTD202X_REG_LED_IOUT(0), KTD202X_LED_CURRENT_10_mA },
82         { KTD202X_REG_LED_IOUT(1), KTD202X_LED_CURRENT_10_mA },
83         { KTD202X_REG_LED_IOUT(2), KTD202X_LED_CURRENT_10_mA },
84         { KTD202X_REG_LED_IOUT(3), KTD202X_LED_CURRENT_10_mA },
85 };
86
87 struct ktd202x_led {
88         struct ktd202x *chip;
89         union {
90                 struct led_classdev cdev;
91                 struct led_classdev_mc mcdev;
92         };
93         u32 index;
94 };
95
96 struct ktd202x {
97         struct mutex mutex;
98         struct regulator_bulk_data regulators[2];
99         struct device *dev;
100         struct regmap *regmap;
101         bool enabled;
102         int num_leds;
103         struct ktd202x_led leds[] __counted_by(num_leds);
104 };
105
106 static int ktd202x_chip_disable(struct ktd202x *chip)
107 {
108         int ret;
109
110         if (!chip->enabled)
111                 return 0;
112
113         regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_SLEEP);
114
115         ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
116         if (ret) {
117                 dev_err(chip->dev, "Failed to disable regulators: %d\n", ret);
118                 return ret;
119         }
120
121         chip->enabled = false;
122         return 0;
123 }
124
125 static int ktd202x_chip_enable(struct ktd202x *chip)
126 {
127         int ret;
128
129         if (chip->enabled)
130                 return 0;
131
132         ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators), chip->regulators);
133         if (ret) {
134                 dev_err(chip->dev, "Failed to enable regulators: %d\n", ret);
135                 return ret;
136         }
137         chip->enabled = true;
138
139         ret = regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_WAKE);
140
141         if (ret) {
142                 dev_err(chip->dev, "Failed to enable the chip: %d\n", ret);
143                 ktd202x_chip_disable(chip);
144         }
145
146         return ret;
147 }
148
149 static bool ktd202x_chip_in_use(struct ktd202x *chip)
150 {
151         int i;
152
153         for (i = 0; i < chip->num_leds; i++) {
154                 if (chip->leds[i].cdev.brightness)
155                         return true;
156         }
157
158         return false;
159 }
160
161 static int ktd202x_brightness_set(struct ktd202x_led *led,
162                                   struct mc_subled *subleds,
163                                   unsigned int num_channels)
164 {
165         bool mode_blink = false;
166         int channel;
167         int state;
168         int ret;
169         int i;
170
171         if (ktd202x_chip_in_use(led->chip)) {
172                 ret = ktd202x_chip_enable(led->chip);
173                 if (ret)
174                         return ret;
175         }
176
177         ret = regmap_read(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL, &state);
178         if (ret)
179                 return ret;
180
181         /*
182          * In multicolor case, assume blink mode if PWM is set for at least one
183          * channel because another channel cannot be in state ON at the same time
184          */
185         for (i = 0; i < num_channels; i++) {
186                 int channel_state;
187
188                 channel = subleds[i].channel;
189                 channel_state = (state >> 2 * channel) & KTD202X_CHANNEL_CTRL_MASK(0);
190                 if (channel_state == KTD202X_CHANNEL_CTRL_OFF)
191                         continue;
192                 mode_blink = channel_state == KTD202X_CHANNEL_CTRL_PWM1(0);
193                 break;
194         }
195
196         for (i = 0; i < num_channels; i++) {
197                 enum led_brightness brightness;
198                 int mode;
199
200                 brightness = subleds[i].brightness;
201                 channel = subleds[i].channel;
202
203                 if (brightness) {
204                         /* Register expects brightness between 0 and MAX_BRIGHTNESS - 1 */
205                         ret = regmap_write(led->chip->regmap, KTD202X_REG_LED_IOUT(channel),
206                                            brightness - 1);
207                         if (ret)
208                                 return ret;
209
210                         if (mode_blink)
211                                 mode = KTD202X_CHANNEL_CTRL_PWM1(channel);
212                         else
213                                 mode = KTD202X_CHANNEL_CTRL_ON(channel);
214                 } else {
215                         mode = KTD202X_CHANNEL_CTRL_OFF;
216                 }
217                 ret = regmap_update_bits(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL,
218                                          KTD202X_CHANNEL_CTRL_MASK(channel), mode);
219                 if (ret)
220                         return ret;
221         }
222
223         if (!ktd202x_chip_in_use(led->chip))
224                 return ktd202x_chip_disable(led->chip);
225
226         return 0;
227 }
228
229 static int ktd202x_brightness_single_set(struct led_classdev *cdev,
230                                          enum led_brightness value)
231 {
232         struct ktd202x_led *led = container_of(cdev, struct ktd202x_led, cdev);
233         struct mc_subled info;
234         int ret;
235
236         cdev->brightness = value;
237
238         mutex_lock(&led->chip->mutex);
239
240         info.brightness = value;
241         info.channel = led->index;
242         ret = ktd202x_brightness_set(led, &info, 1);
243
244         mutex_unlock(&led->chip->mutex);
245
246         return ret;
247 }
248
249 static int ktd202x_brightness_mc_set(struct led_classdev *cdev,
250                                      enum led_brightness value)
251 {
252         struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
253         struct ktd202x_led *led = container_of(mc, struct ktd202x_led, mcdev);
254         int ret;
255
256         cdev->brightness = value;
257
258         mutex_lock(&led->chip->mutex);
259
260         led_mc_calc_color_components(mc, value);
261         ret = ktd202x_brightness_set(led, mc->subled_info, mc->num_colors);
262
263         mutex_unlock(&led->chip->mutex);
264
265         return ret;
266 }
267
268 static int ktd202x_blink_set(struct ktd202x_led *led, unsigned long *delay_on,
269                              unsigned long *delay_off, struct mc_subled *subleds,
270                              unsigned int num_channels)
271 {
272         unsigned long delay_total_ms;
273         int ret, num_steps, on;
274         u8 ctrl_mask = 0;
275         u8 ctrl_pwm1 = 0;
276         u8 ctrl_on = 0;
277         int i;
278
279         mutex_lock(&led->chip->mutex);
280
281         for (i = 0; i < num_channels; i++) {
282                 int channel = subleds[i].channel;
283
284                 ctrl_mask |= KTD202X_CHANNEL_CTRL_MASK(channel);
285                 ctrl_on |= KTD202X_CHANNEL_CTRL_ON(channel);
286                 ctrl_pwm1 |= KTD202X_CHANNEL_CTRL_PWM1(channel);
287         }
288
289         /* Never off - brightness is already set, disable blinking */
290         if (!*delay_off) {
291                 ret = regmap_update_bits(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL,
292                                          ctrl_mask, ctrl_on);
293                 goto out;
294         }
295
296         /* Convert into values the HW will understand. */
297
298         /* Integer representation of time of flash period */
299         num_steps = (*delay_on + *delay_off - KTD202X_FLASH_PERIOD_MIN_MS) /
300                     KTD202X_FLASH_PERIOD_STEP_MS;
301         num_steps = clamp(num_steps, 0, KTD202X_FLASH_PERIOD_MAX_STEPS);
302
303         /* Integer representation of percentage of LED ON time */
304         on = (*delay_on * KTD202X_FLASH_ON_MAX) / (*delay_on + *delay_off);
305
306         /* Actually used delay_{on,off} values */
307         delay_total_ms = num_steps * KTD202X_FLASH_PERIOD_STEP_MS + KTD202X_FLASH_PERIOD_MIN_MS;
308         *delay_on = (delay_total_ms * on) / KTD202X_FLASH_ON_MAX;
309         *delay_off = delay_total_ms - *delay_on;
310
311         /* Set timings */
312         ret = regmap_write(led->chip->regmap, KTD202X_REG_FLASH_PERIOD, num_steps);
313         if (ret)
314                 goto out;
315
316         ret = regmap_write(led->chip->regmap, KTD202X_REG_PWM1_TIMER, on);
317         if (ret)
318                 goto out;
319
320         ret = regmap_update_bits(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL,
321                                  ctrl_mask, ctrl_pwm1);
322 out:
323         mutex_unlock(&led->chip->mutex);
324         return ret;
325 }
326
327 static int ktd202x_blink_single_set(struct led_classdev *cdev,
328                                     unsigned long *delay_on,
329                                     unsigned long *delay_off)
330 {
331         struct ktd202x_led *led = container_of(cdev, struct ktd202x_led, cdev);
332         struct mc_subled info;
333         int ret;
334
335         if (!cdev->brightness) {
336                 ret = ktd202x_brightness_single_set(cdev, KTD202X_MAX_BRIGHTNESS);
337                 if (ret)
338                         return ret;
339         }
340
341         /* If no blink specified, default to 1 Hz. */
342         if (!*delay_off && !*delay_on) {
343                 *delay_off = 500;
344                 *delay_on = 500;
345         }
346
347         /* Never on - just set to off */
348         if (!*delay_on)
349                 return ktd202x_brightness_single_set(cdev, LED_OFF);
350
351         info.channel = led->index;
352
353         return ktd202x_blink_set(led, delay_on, delay_off, &info, 1);
354 }
355
356 static int ktd202x_blink_mc_set(struct led_classdev *cdev,
357                                 unsigned long *delay_on,
358                                 unsigned long *delay_off)
359 {
360         struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
361         struct ktd202x_led *led = container_of(mc, struct ktd202x_led, mcdev);
362         int ret;
363
364         if (!cdev->brightness) {
365                 ret = ktd202x_brightness_mc_set(cdev, KTD202X_MAX_BRIGHTNESS);
366                 if (ret)
367                         return ret;
368         }
369
370         /* If no blink specified, default to 1 Hz. */
371         if (!*delay_off && !*delay_on) {
372                 *delay_off = 500;
373                 *delay_on = 500;
374         }
375
376         /* Never on - just set to off */
377         if (!*delay_on)
378                 return ktd202x_brightness_mc_set(cdev, LED_OFF);
379
380         return ktd202x_blink_set(led, delay_on, delay_off, mc->subled_info,
381                                  mc->num_colors);
382 }
383
384 static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct device_node *np,
385                                  struct ktd202x_led *led, struct led_init_data *init_data)
386 {
387         struct led_classdev *cdev;
388         struct device_node *child;
389         struct mc_subled *info;
390         int num_channels;
391         int i = 0;
392
393         num_channels = of_get_available_child_count(np);
394         if (!num_channels || num_channels > chip->num_leds)
395                 return -EINVAL;
396
397         info = devm_kcalloc(chip->dev, num_channels, sizeof(*info), GFP_KERNEL);
398         if (!info)
399                 return -ENOMEM;
400
401         for_each_available_child_of_node(np, child) {
402                 u32 mono_color;
403                 u32 reg;
404                 int ret;
405
406                 ret = of_property_read_u32(child, "reg", &reg);
407                 if (ret != 0 || reg >= chip->num_leds) {
408                         dev_err(chip->dev, "invalid 'reg' of %pOFn\n", child);
409                         of_node_put(child);
410                         return -EINVAL;
411                 }
412
413                 ret = of_property_read_u32(child, "color", &mono_color);
414                 if (ret < 0 && ret != -EINVAL) {
415                         dev_err(chip->dev, "failed to parse 'color' of %pOF\n", child);
416                         of_node_put(child);
417                         return ret;
418                 }
419
420                 info[i].color_index = mono_color;
421                 info[i].channel = reg;
422                 info[i].intensity = KTD202X_MAX_BRIGHTNESS;
423                 i++;
424         }
425
426         led->mcdev.subled_info = info;
427         led->mcdev.num_colors = num_channels;
428
429         cdev = &led->mcdev.led_cdev;
430         cdev->brightness_set_blocking = ktd202x_brightness_mc_set;
431         cdev->blink_set = ktd202x_blink_mc_set;
432
433         return devm_led_classdev_multicolor_register_ext(chip->dev, &led->mcdev, init_data);
434 }
435
436 static int ktd202x_setup_led_single(struct ktd202x *chip, struct device_node *np,
437                                     struct ktd202x_led *led, struct led_init_data *init_data)
438 {
439         struct led_classdev *cdev;
440         u32 reg;
441         int ret;
442
443         ret = of_property_read_u32(np, "reg", &reg);
444         if (ret != 0 || reg >= chip->num_leds) {
445                 dev_err(chip->dev, "invalid 'reg' of %pOFn\n", np);
446                 return -EINVAL;
447         }
448         led->index = reg;
449
450         cdev = &led->cdev;
451         cdev->brightness_set_blocking = ktd202x_brightness_single_set;
452         cdev->blink_set = ktd202x_blink_single_set;
453
454         return devm_led_classdev_register_ext(chip->dev, &led->cdev, init_data);
455 }
456
457 static int ktd202x_add_led(struct ktd202x *chip, struct device_node *np, unsigned int index)
458 {
459         struct ktd202x_led *led = &chip->leds[index];
460         struct led_init_data init_data = {};
461         struct led_classdev *cdev;
462         u32 color;
463         int ret;
464
465         /* Color property is optional in single color case */
466         ret = of_property_read_u32(np, "color", &color);
467         if (ret < 0 && ret != -EINVAL) {
468                 dev_err(chip->dev, "failed to parse 'color' of %pOF\n", np);
469                 return ret;
470         }
471
472         led->chip = chip;
473         init_data.fwnode = of_fwnode_handle(np);
474
475         if (color == LED_COLOR_ID_RGB) {
476                 cdev = &led->mcdev.led_cdev;
477                 ret = ktd202x_setup_led_rgb(chip, np, led, &init_data);
478         } else {
479                 cdev = &led->cdev;
480                 ret = ktd202x_setup_led_single(chip, np, led, &init_data);
481         }
482
483         if (ret) {
484                 dev_err(chip->dev, "unable to register %s\n", cdev->name);
485                 return ret;
486         }
487
488         cdev->max_brightness = KTD202X_MAX_BRIGHTNESS;
489
490         return 0;
491 }
492
493 static int ktd202x_probe_dt(struct ktd202x *chip)
494 {
495         struct device_node *np = dev_of_node(chip->dev), *child;
496         int count;
497         int i = 0;
498
499         chip->num_leds = (int)(unsigned long)of_device_get_match_data(chip->dev);
500
501         count = of_get_available_child_count(np);
502         if (!count || count > chip->num_leds)
503                 return -EINVAL;
504
505         regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_RSTR_RESET);
506
507         /* Allow the device to execute the complete reset */
508         usleep_range(200, 300);
509
510         for_each_available_child_of_node(np, child) {
511                 int ret = ktd202x_add_led(chip, child, i);
512
513                 if (ret) {
514                         of_node_put(child);
515                         return ret;
516                 }
517                 i++;
518         }
519
520         return 0;
521 }
522
523 static const struct regmap_config ktd202x_regmap_config = {
524         .reg_bits = 8,
525         .val_bits = 8,
526         .max_register = 0x09,
527         .cache_type = REGCACHE_FLAT,
528         .reg_defaults = ktd202x_reg_defaults,
529         .num_reg_defaults = ARRAY_SIZE(ktd202x_reg_defaults),
530 };
531
532 static int ktd202x_probe(struct i2c_client *client)
533 {
534         struct device *dev = &client->dev;
535         struct ktd202x *chip;
536         int count;
537         int ret;
538
539         count = device_get_child_node_count(dev);
540         if (!count || count > KTD202X_MAX_LEDS)
541                 return dev_err_probe(dev, -EINVAL, "Incorrect number of leds (%d)", count);
542
543         chip = devm_kzalloc(dev, struct_size(chip, leds, count), GFP_KERNEL);
544         if (!chip)
545                 return -ENOMEM;
546
547         chip->dev = dev;
548         i2c_set_clientdata(client, chip);
549
550         chip->regmap = devm_regmap_init_i2c(client, &ktd202x_regmap_config);
551         if (IS_ERR(chip->regmap)) {
552                 ret = dev_err_probe(dev, PTR_ERR(chip->regmap),
553                                     "Failed to allocate register map.\n");
554                 return ret;
555         }
556
557         chip->regulators[0].supply = "vin";
558         chip->regulators[1].supply = "vio";
559         ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators);
560         if (ret < 0) {
561                 dev_err_probe(dev, ret, "Failed to request regulators.\n");
562                 return ret;
563         }
564
565         ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators), chip->regulators);
566         if (ret) {
567                 dev_err_probe(dev, ret, "Failed to enable regulators.\n");
568                 return ret;
569         }
570
571         ret = ktd202x_probe_dt(chip);
572         if (ret < 0) {
573                 regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
574                 return ret;
575         }
576
577         ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators);
578         if (ret) {
579                 dev_err_probe(dev, ret, "Failed to disable regulators.\n");
580                 return ret;
581         }
582
583         mutex_init(&chip->mutex);
584
585         return 0;
586 }
587
588 static void ktd202x_remove(struct i2c_client *client)
589 {
590         struct ktd202x *chip = i2c_get_clientdata(client);
591
592         ktd202x_chip_disable(chip);
593
594         mutex_destroy(&chip->mutex);
595 }
596
597 static void ktd202x_shutdown(struct i2c_client *client)
598 {
599         struct ktd202x *chip = i2c_get_clientdata(client);
600
601         /* Reset registers to make sure all LEDs are off before shutdown */
602         regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_RSTR_RESET);
603 }
604
605 static const struct of_device_id ktd202x_match_table[] = {
606         { .compatible = "kinetic,ktd2026", .data = (void *)KTD2026_NUM_LEDS },
607         { .compatible = "kinetic,ktd2027", .data = (void *)KTD2027_NUM_LEDS },
608         {},
609 };
610 MODULE_DEVICE_TABLE(of, ktd202x_match_table);
611
612 static struct i2c_driver ktd202x_driver = {
613         .driver = {
614                 .name = "leds-ktd202x",
615                 .of_match_table = ktd202x_match_table,
616         },
617         .probe = ktd202x_probe,
618         .remove = ktd202x_remove,
619         .shutdown = ktd202x_shutdown,
620 };
621 module_i2c_driver(ktd202x_driver);
622
623 MODULE_AUTHOR("AndrĂ© Apitzsch <git@apitzsch.eu>");
624 MODULE_DESCRIPTION("Kinetic KTD2026/7 LED driver");
625 MODULE_LICENSE("GPL");