drm/tests: hdmi: Fix memory leaks in drm_display_mode_from_cea_vic()
[drm/drm-misc.git] / drivers / leds / leds-aw200xx.c
blobf9d9844e027380f84ef721d8e29a4abbf50cfe9d
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Awinic AW20036/AW20054/AW20072/AW20108 LED driver
5 * Copyright (c) 2023, SberDevices. All Rights Reserved.
7 * Author: Martin Kurbanov <mmkurbanov@sberdevices.ru>
8 */
10 #include <linux/bitfield.h>
11 #include <linux/bits.h>
12 #include <linux/container_of.h>
13 #include <linux/gpio/consumer.h>
14 #include <linux/i2c.h>
15 #include <linux/leds.h>
16 #include <linux/mod_devicetable.h>
17 #include <linux/module.h>
18 #include <linux/mutex.h>
19 #include <linux/regmap.h>
20 #include <linux/time.h>
21 #include <linux/units.h>
23 #define AW200XX_DIM_MAX (BIT(6) - 1)
24 #define AW200XX_FADE_MAX (BIT(8) - 1)
25 #define AW200XX_IMAX_DEFAULT_uA 60000
26 #define AW200XX_IMAX_MAX_uA 160000
27 #define AW200XX_IMAX_MIN_uA 3300
29 /* Page 0 */
30 #define AW200XX_REG_PAGE0_BASE 0xc000
32 /* Select page register */
33 #define AW200XX_REG_PAGE 0xF0
34 #define AW200XX_PAGE_MASK (GENMASK(7, 6) | GENMASK(2, 0))
35 #define AW200XX_PAGE_SHIFT 0
36 #define AW200XX_NUM_PAGES 6
37 #define AW200XX_PAGE_SIZE 256
38 #define AW200XX_REG(page, reg) \
39 (AW200XX_REG_PAGE0_BASE + (page) * AW200XX_PAGE_SIZE + (reg))
40 #define AW200XX_REG_MAX \
41 AW200XX_REG(AW200XX_NUM_PAGES - 1, AW200XX_PAGE_SIZE - 1)
42 #define AW200XX_PAGE0 0
43 #define AW200XX_PAGE1 1
44 #define AW200XX_PAGE2 2
45 #define AW200XX_PAGE3 3
46 #define AW200XX_PAGE4 4
47 #define AW200XX_PAGE5 5
49 /* Chip ID register */
50 #define AW200XX_REG_IDR AW200XX_REG(AW200XX_PAGE0, 0x00)
51 #define AW200XX_IDR_CHIPID 0x18
53 /* Sleep mode register */
54 #define AW200XX_REG_SLPCR AW200XX_REG(AW200XX_PAGE0, 0x01)
55 #define AW200XX_SLPCR_ACTIVE 0x00
57 /* Reset register */
58 #define AW200XX_REG_RSTR AW200XX_REG(AW200XX_PAGE0, 0x02)
59 #define AW200XX_RSTR_RESET 0x01
61 /* Global current configuration register */
62 #define AW200XX_REG_GCCR AW200XX_REG(AW200XX_PAGE0, 0x03)
63 #define AW200XX_GCCR_IMAX_MASK GENMASK(7, 4)
64 #define AW200XX_GCCR_IMAX(x) ((x) << 4)
65 #define AW200XX_GCCR_ALLON BIT(3)
67 /* Fast clear display control register */
68 #define AW200XX_REG_FCD AW200XX_REG(AW200XX_PAGE0, 0x04)
69 #define AW200XX_FCD_CLEAR 0x01
71 /* Display size configuration */
72 #define AW200XX_REG_DSIZE AW200XX_REG(AW200XX_PAGE0, 0x80)
73 #define AW200XX_DSIZE_COLUMNS_MAX 12
75 #define AW200XX_LED2REG(x, columns) \
76 ((x) + (((x) / (columns)) * (AW200XX_DSIZE_COLUMNS_MAX - (columns))))
78 /* DIM current configuration register on page 1 */
79 #define AW200XX_REG_DIM_PAGE1(x, columns) \
80 AW200XX_REG(AW200XX_PAGE1, AW200XX_LED2REG(x, columns))
83 * DIM current configuration register (page 4).
84 * The even address for current DIM configuration.
85 * The odd address for current FADE configuration
87 #define AW200XX_REG_DIM(x, columns) \
88 AW200XX_REG(AW200XX_PAGE4, AW200XX_LED2REG(x, columns) * 2)
89 #define AW200XX_REG_DIM2FADE(x) ((x) + 1)
90 #define AW200XX_REG_FADE2DIM(fade) \
91 DIV_ROUND_UP((fade) * AW200XX_DIM_MAX, AW200XX_FADE_MAX)
94 * Duty ratio of display scan (see p.15 of datasheet for formula):
95 * duty = (592us / 600.5us) * (1 / (display_rows + 1))
97 * Multiply to 1000 (MILLI) to improve the accuracy of calculations.
99 #define AW200XX_DUTY_RATIO(rows) \
100 (((592UL * USEC_PER_SEC) / 600500UL) * (MILLI / (rows)) / MILLI)
102 struct aw200xx_chipdef {
103 u32 channels;
104 u32 display_size_rows_max;
105 u32 display_size_columns;
108 struct aw200xx_led {
109 struct led_classdev cdev;
110 struct aw200xx *chip;
111 int dim;
112 u32 num;
115 struct aw200xx {
116 const struct aw200xx_chipdef *cdef;
117 struct i2c_client *client;
118 struct regmap *regmap;
119 struct mutex mutex;
120 u32 num_leds;
121 u32 display_rows;
122 struct gpio_desc *hwen;
123 struct aw200xx_led leds[] __counted_by(num_leds);
126 static ssize_t dim_show(struct device *dev, struct device_attribute *devattr,
127 char *buf)
129 struct led_classdev *cdev = dev_get_drvdata(dev);
130 struct aw200xx_led *led = container_of(cdev, struct aw200xx_led, cdev);
131 int dim = led->dim;
133 if (dim < 0)
134 return sysfs_emit(buf, "auto\n");
136 return sysfs_emit(buf, "%d\n", dim);
139 static ssize_t dim_store(struct device *dev, struct device_attribute *devattr,
140 const char *buf, size_t count)
142 struct led_classdev *cdev = dev_get_drvdata(dev);
143 struct aw200xx_led *led = container_of(cdev, struct aw200xx_led, cdev);
144 struct aw200xx *chip = led->chip;
145 u32 columns = chip->cdef->display_size_columns;
146 int dim;
147 ssize_t ret;
149 if (sysfs_streq(buf, "auto")) {
150 dim = -1;
151 } else {
152 ret = kstrtoint(buf, 0, &dim);
153 if (ret)
154 return ret;
156 if (dim > AW200XX_DIM_MAX)
157 return -EINVAL;
160 mutex_lock(&chip->mutex);
162 if (dim >= 0) {
163 ret = regmap_write(chip->regmap,
164 AW200XX_REG_DIM_PAGE1(led->num, columns),
165 dim);
166 if (ret)
167 goto out_unlock;
170 led->dim = dim;
171 ret = count;
173 out_unlock:
174 mutex_unlock(&chip->mutex);
175 return ret;
177 static DEVICE_ATTR_RW(dim);
179 static struct attribute *dim_attrs[] = {
180 &dev_attr_dim.attr,
181 NULL
183 ATTRIBUTE_GROUPS(dim);
185 static int aw200xx_brightness_set(struct led_classdev *cdev,
186 enum led_brightness brightness)
188 struct aw200xx_led *led = container_of(cdev, struct aw200xx_led, cdev);
189 struct aw200xx *chip = led->chip;
190 int dim;
191 u32 reg;
192 int ret;
194 mutex_lock(&chip->mutex);
196 reg = AW200XX_REG_DIM(led->num, chip->cdef->display_size_columns);
198 dim = led->dim;
199 if (dim < 0)
200 dim = AW200XX_REG_FADE2DIM(brightness);
202 ret = regmap_write(chip->regmap, reg, dim);
203 if (ret)
204 goto out_unlock;
206 ret = regmap_write(chip->regmap,
207 AW200XX_REG_DIM2FADE(reg), brightness);
209 out_unlock:
210 mutex_unlock(&chip->mutex);
212 return ret;
215 static u32 aw200xx_imax_from_global(const struct aw200xx *const chip,
216 u32 global_imax_uA)
218 u64 led_imax_uA;
221 * The output current of each LED (see p.14 of datasheet for formula):
222 * Iled = Imax * (dim / 63) * ((fade + 1) / 256) * duty
224 * The value of duty is determined by the following formula:
225 * duty = (592us / 600.5us) * (1 / (display_rows + 1))
227 * Calculated for the maximum values of fade and dim.
228 * We divide by 1000 because we earlier multiplied by 1000 to improve
229 * accuracy when calculating the duty.
231 led_imax_uA = global_imax_uA * AW200XX_DUTY_RATIO(chip->display_rows);
232 do_div(led_imax_uA, MILLI);
234 return led_imax_uA;
237 static u32 aw200xx_imax_to_global(const struct aw200xx *const chip,
238 u32 led_imax_uA)
240 u32 duty = AW200XX_DUTY_RATIO(chip->display_rows);
242 /* The output current of each LED (see p.14 of datasheet for formula) */
243 return (led_imax_uA * 1000U) / duty;
246 #define AW200XX_IMAX_MULTIPLIER1 10000
247 #define AW200XX_IMAX_MULTIPLIER2 3333
248 #define AW200XX_IMAX_BASE_VAL1 0
249 #define AW200XX_IMAX_BASE_VAL2 8
252 * The AW200XX has a 4-bit register (GCCR) to configure the global current,
253 * which ranges from 3.3mA to 160mA. The following table indicates the values
254 * of the global current, divided into two parts:
256 * +-----------+-----------------+-----------+-----------------+
257 * | reg value | global max (mA) | reg value | global max (mA) |
258 * +-----------+-----------------+-----------+-----------------+
259 * | 0 | 10 | 8 | 3.3 |
260 * | 1 | 20 | 9 | 6.7 |
261 * | 2 | 30 | 10 | 10 |
262 * | 3 | 40 | 11 | 13.3 |
263 * | 4 | 60 | 12 | 20 |
264 * | 5 | 80 | 13 | 26.7 |
265 * | 6 | 120 | 14 | 40 |
266 * | 7 | 160 | 15 | 53.3 |
267 * +-----------+-----------------+-----------+-----------------+
269 * The left part with a multiplier of 10, and the right part with a multiplier
270 * of 3.3.
271 * So we have two formulas to calculate the global current:
272 * for the left part of the table:
273 * imax = coefficient * 10
275 * for the right part of the table:
276 * imax = coefficient * 3.3
278 * The coefficient table consists of the following values:
279 * 1, 2, 3, 4, 6, 8, 12, 16.
281 static int aw200xx_set_imax(const struct aw200xx *const chip,
282 u32 led_imax_uA)
284 u32 g_imax_uA = aw200xx_imax_to_global(chip, led_imax_uA);
285 static const u32 coeff_table[] = {1, 2, 3, 4, 6, 8, 12, 16};
286 u32 gccr_imax = UINT_MAX;
287 u32 cur_imax = 0;
288 int i;
290 for (i = 0; i < ARRAY_SIZE(coeff_table); i++) {
291 u32 imax;
293 /* select closest ones */
294 imax = coeff_table[i] * AW200XX_IMAX_MULTIPLIER1;
295 if (g_imax_uA >= imax && imax > cur_imax) {
296 cur_imax = imax;
297 gccr_imax = i + AW200XX_IMAX_BASE_VAL1;
300 imax = coeff_table[i] * AW200XX_IMAX_MULTIPLIER2;
301 imax = DIV_ROUND_CLOSEST(imax, 100) * 100;
302 if (g_imax_uA >= imax && imax > cur_imax) {
303 cur_imax = imax;
304 gccr_imax = i + AW200XX_IMAX_BASE_VAL2;
308 if (gccr_imax == UINT_MAX)
309 return -EINVAL;
311 return regmap_update_bits(chip->regmap, AW200XX_REG_GCCR,
312 AW200XX_GCCR_IMAX_MASK,
313 AW200XX_GCCR_IMAX(gccr_imax));
316 static int aw200xx_chip_reset(const struct aw200xx *const chip)
318 int ret;
320 ret = regmap_write(chip->regmap, AW200XX_REG_RSTR, AW200XX_RSTR_RESET);
321 if (ret)
322 return ret;
324 /* According to the datasheet software reset takes at least 1ms */
325 fsleep(1000);
327 regcache_mark_dirty(chip->regmap);
328 return regmap_write(chip->regmap, AW200XX_REG_FCD, AW200XX_FCD_CLEAR);
331 static int aw200xx_chip_init(const struct aw200xx *const chip)
333 int ret;
335 ret = regmap_write(chip->regmap, AW200XX_REG_DSIZE,
336 chip->display_rows - 1);
337 if (ret)
338 return ret;
340 ret = regmap_write(chip->regmap, AW200XX_REG_SLPCR,
341 AW200XX_SLPCR_ACTIVE);
342 if (ret)
343 return ret;
345 return regmap_update_bits(chip->regmap, AW200XX_REG_GCCR,
346 AW200XX_GCCR_ALLON, AW200XX_GCCR_ALLON);
349 static int aw200xx_chip_check(const struct aw200xx *const chip)
351 struct device *dev = &chip->client->dev;
352 u32 chipid;
353 int ret;
355 ret = regmap_read(chip->regmap, AW200XX_REG_IDR, &chipid);
356 if (ret)
357 return dev_err_probe(dev, ret, "Failed to read chip ID\n");
359 if (chipid != AW200XX_IDR_CHIPID)
360 return dev_err_probe(dev, -ENODEV,
361 "Chip reported wrong ID: %x\n", chipid);
363 return 0;
366 static void aw200xx_enable(const struct aw200xx *const chip)
368 gpiod_set_value_cansleep(chip->hwen, 1);
371 * After HWEN pin set high the chip begins to load the OTP information,
372 * which takes 200us to complete. About 200us wait time is needed for
373 * internal oscillator startup and display SRAM initialization. After
374 * display SRAM initialization, the registers in page1 to page5 can be
375 * configured via i2c interface.
377 fsleep(400);
380 static void aw200xx_disable(const struct aw200xx *const chip)
382 return gpiod_set_value_cansleep(chip->hwen, 0);
385 static int aw200xx_probe_get_display_rows(struct device *dev,
386 struct aw200xx *chip)
388 struct fwnode_handle *child;
389 u32 max_source = 0;
391 device_for_each_child_node(dev, child) {
392 u32 source;
393 int ret;
395 ret = fwnode_property_read_u32(child, "reg", &source);
396 if (ret || source >= chip->cdef->channels)
397 continue;
399 max_source = max(max_source, source);
402 if (max_source == 0)
403 return -EINVAL;
405 chip->display_rows = max_source / chip->cdef->display_size_columns + 1;
407 return 0;
410 static int aw200xx_probe_fw(struct device *dev, struct aw200xx *chip)
412 struct fwnode_handle *child;
413 u32 current_min, current_max, min_uA;
414 int ret;
415 int i;
417 ret = aw200xx_probe_get_display_rows(dev, chip);
418 if (ret)
419 return dev_err_probe(dev, ret,
420 "No valid led definitions found\n");
422 current_max = aw200xx_imax_from_global(chip, AW200XX_IMAX_MAX_uA);
423 current_min = aw200xx_imax_from_global(chip, AW200XX_IMAX_MIN_uA);
424 min_uA = UINT_MAX;
425 i = 0;
427 device_for_each_child_node(dev, child) {
428 struct led_init_data init_data = {};
429 struct aw200xx_led *led;
430 u32 source, imax;
432 ret = fwnode_property_read_u32(child, "reg", &source);
433 if (ret) {
434 dev_err(dev, "Missing reg property\n");
435 chip->num_leds--;
436 continue;
439 if (source >= chip->cdef->channels) {
440 dev_err(dev, "LED reg %u out of range (max %u)\n",
441 source, chip->cdef->channels);
442 chip->num_leds--;
443 continue;
446 ret = fwnode_property_read_u32(child, "led-max-microamp",
447 &imax);
448 if (ret) {
449 dev_info(&chip->client->dev,
450 "DT property led-max-microamp is missing\n");
451 } else if (imax < current_min || imax > current_max) {
452 dev_err(dev, "Invalid value %u for led-max-microamp\n",
453 imax);
454 chip->num_leds--;
455 continue;
456 } else {
457 min_uA = min(min_uA, imax);
460 led = &chip->leds[i];
461 led->dim = -1;
462 led->num = source;
463 led->chip = chip;
464 led->cdev.brightness_set_blocking = aw200xx_brightness_set;
465 led->cdev.max_brightness = AW200XX_FADE_MAX;
466 led->cdev.groups = dim_groups;
467 init_data.fwnode = child;
469 ret = devm_led_classdev_register_ext(dev, &led->cdev,
470 &init_data);
471 if (ret) {
472 fwnode_handle_put(child);
473 break;
476 i++;
479 if (!chip->num_leds)
480 return -EINVAL;
482 if (min_uA == UINT_MAX) {
483 min_uA = aw200xx_imax_from_global(chip,
484 AW200XX_IMAX_DEFAULT_uA);
487 return aw200xx_set_imax(chip, min_uA);
490 static const struct regmap_range_cfg aw200xx_ranges[] = {
492 .name = "aw200xx",
493 .range_min = 0,
494 .range_max = AW200XX_REG_MAX,
495 .selector_reg = AW200XX_REG_PAGE,
496 .selector_mask = AW200XX_PAGE_MASK,
497 .selector_shift = AW200XX_PAGE_SHIFT,
498 .window_start = 0,
499 .window_len = AW200XX_PAGE_SIZE,
503 static const struct regmap_range aw200xx_writeonly_ranges[] = {
504 regmap_reg_range(AW200XX_REG(AW200XX_PAGE1, 0x00), AW200XX_REG_MAX),
507 static const struct regmap_access_table aw200xx_readable_table = {
508 .no_ranges = aw200xx_writeonly_ranges,
509 .n_no_ranges = ARRAY_SIZE(aw200xx_writeonly_ranges),
512 static const struct regmap_range aw200xx_readonly_ranges[] = {
513 regmap_reg_range(AW200XX_REG_IDR, AW200XX_REG_IDR),
516 static const struct regmap_access_table aw200xx_writeable_table = {
517 .no_ranges = aw200xx_readonly_ranges,
518 .n_no_ranges = ARRAY_SIZE(aw200xx_readonly_ranges),
521 static const struct regmap_config aw200xx_regmap_config = {
522 .reg_bits = 8,
523 .val_bits = 8,
524 .max_register = AW200XX_REG_MAX,
525 .ranges = aw200xx_ranges,
526 .num_ranges = ARRAY_SIZE(aw200xx_ranges),
527 .rd_table = &aw200xx_readable_table,
528 .wr_table = &aw200xx_writeable_table,
529 .cache_type = REGCACHE_MAPLE,
530 .disable_locking = true,
533 static void aw200xx_chip_reset_action(void *data)
535 aw200xx_chip_reset(data);
538 static void aw200xx_disable_action(void *data)
540 aw200xx_disable(data);
543 static int aw200xx_probe(struct i2c_client *client)
545 const struct aw200xx_chipdef *cdef;
546 struct aw200xx *chip;
547 int count;
548 int ret;
550 cdef = device_get_match_data(&client->dev);
551 if (!cdef)
552 return -ENODEV;
554 count = device_get_child_node_count(&client->dev);
555 if (!count || count > cdef->channels)
556 return dev_err_probe(&client->dev, -EINVAL,
557 "Incorrect number of leds (%d)", count);
559 chip = devm_kzalloc(&client->dev, struct_size(chip, leds, count),
560 GFP_KERNEL);
561 if (!chip)
562 return -ENOMEM;
564 chip->cdef = cdef;
565 chip->num_leds = count;
566 chip->client = client;
567 i2c_set_clientdata(client, chip);
569 chip->regmap = devm_regmap_init_i2c(client, &aw200xx_regmap_config);
570 if (IS_ERR(chip->regmap))
571 return PTR_ERR(chip->regmap);
573 chip->hwen = devm_gpiod_get_optional(&client->dev, "enable",
574 GPIOD_OUT_HIGH);
575 if (IS_ERR(chip->hwen))
576 return dev_err_probe(&client->dev, PTR_ERR(chip->hwen),
577 "Cannot get enable GPIO");
579 aw200xx_enable(chip);
581 ret = devm_add_action(&client->dev, aw200xx_disable_action, chip);
582 if (ret)
583 return ret;
585 ret = aw200xx_chip_check(chip);
586 if (ret)
587 return ret;
589 ret = devm_mutex_init(&client->dev, &chip->mutex);
590 if (ret)
591 return ret;
593 /* Need a lock now since after call aw200xx_probe_fw, sysfs nodes created */
594 mutex_lock(&chip->mutex);
596 ret = aw200xx_chip_reset(chip);
597 if (ret)
598 goto out_unlock;
600 ret = devm_add_action(&client->dev, aw200xx_chip_reset_action, chip);
601 if (ret)
602 goto out_unlock;
604 ret = aw200xx_probe_fw(&client->dev, chip);
605 if (ret)
606 goto out_unlock;
608 ret = aw200xx_chip_init(chip);
610 out_unlock:
611 if (ret)
612 aw200xx_disable(chip);
614 mutex_unlock(&chip->mutex);
615 return ret;
618 static const struct aw200xx_chipdef aw20036_cdef = {
619 .channels = 36,
620 .display_size_rows_max = 3,
621 .display_size_columns = 12,
624 static const struct aw200xx_chipdef aw20054_cdef = {
625 .channels = 54,
626 .display_size_rows_max = 6,
627 .display_size_columns = 9,
630 static const struct aw200xx_chipdef aw20072_cdef = {
631 .channels = 72,
632 .display_size_rows_max = 6,
633 .display_size_columns = 12,
636 static const struct aw200xx_chipdef aw20108_cdef = {
637 .channels = 108,
638 .display_size_rows_max = 9,
639 .display_size_columns = 12,
642 static const struct i2c_device_id aw200xx_id[] = {
643 { "aw20036" },
644 { "aw20054" },
645 { "aw20072" },
646 { "aw20108" },
649 MODULE_DEVICE_TABLE(i2c, aw200xx_id);
651 static const struct of_device_id aw200xx_match_table[] = {
652 { .compatible = "awinic,aw20036", .data = &aw20036_cdef, },
653 { .compatible = "awinic,aw20054", .data = &aw20054_cdef, },
654 { .compatible = "awinic,aw20072", .data = &aw20072_cdef, },
655 { .compatible = "awinic,aw20108", .data = &aw20108_cdef, },
658 MODULE_DEVICE_TABLE(of, aw200xx_match_table);
660 static struct i2c_driver aw200xx_driver = {
661 .driver = {
662 .name = "aw200xx",
663 .of_match_table = aw200xx_match_table,
665 .probe = aw200xx_probe,
666 .id_table = aw200xx_id,
668 module_i2c_driver(aw200xx_driver);
670 MODULE_AUTHOR("Martin Kurbanov <mmkurbanov@sberdevices.ru>");
671 MODULE_DESCRIPTION("AW200XX LED driver");
672 MODULE_LICENSE("GPL");