hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/leds/leds-lp55xx-common.c
....@@ -1,13 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * LP5521/LP5523/LP55231/LP5562 Common Driver
34 *
45 * Copyright 2012 Texas Instruments
56 *
67 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License version 2 as
10
- * published by the Free Software Foundation.
118 *
129 * Derived from leds-lp5521.c, leds-lp5523.c
1310 */
....@@ -20,8 +17,7 @@
2017 #include <linux/module.h>
2118 #include <linux/platform_data/leds-lp55xx.h>
2219 #include <linux/slab.h>
23
-#include <linux/gpio.h>
24
-#include <linux/of_gpio.h>
20
+#include <linux/gpio/consumer.h>
2521
2622 #include "leds-lp55xx-common.h"
2723
....@@ -36,6 +32,11 @@
3632 static struct lp55xx_led *dev_to_lp55xx_led(struct device *dev)
3733 {
3834 return cdev_to_lp55xx_led(dev_get_drvdata(dev));
35
+}
36
+
37
+static struct lp55xx_led *mcled_cdev_to_led(struct led_classdev_mc *mc_cdev)
38
+{
39
+ return container_of(mc_cdev, struct lp55xx_led, mc_cdev);
3940 }
4041
4142 static void lp55xx_reset_device(struct lp55xx_chip *chip)
....@@ -81,7 +82,7 @@
8182 return cfg->post_init_device(chip);
8283 }
8384
84
-static ssize_t lp55xx_show_current(struct device *dev,
85
+static ssize_t led_current_show(struct device *dev,
8586 struct device_attribute *attr,
8687 char *buf)
8788 {
....@@ -90,7 +91,7 @@
9091 return scnprintf(buf, PAGE_SIZE, "%d\n", led->led_current);
9192 }
9293
93
-static ssize_t lp55xx_store_current(struct device *dev,
94
+static ssize_t led_current_store(struct device *dev,
9495 struct device_attribute *attr,
9596 const char *buf, size_t len)
9697 {
....@@ -114,7 +115,7 @@
114115 return len;
115116 }
116117
117
-static ssize_t lp55xx_show_max_current(struct device *dev,
118
+static ssize_t max_current_show(struct device *dev,
118119 struct device_attribute *attr,
119120 char *buf)
120121 {
....@@ -123,9 +124,8 @@
123124 return scnprintf(buf, PAGE_SIZE, "%d\n", led->max_current);
124125 }
125126
126
-static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, lp55xx_show_current,
127
- lp55xx_store_current);
128
-static DEVICE_ATTR(max_current, S_IRUGO , lp55xx_show_max_current, NULL);
127
+static DEVICE_ATTR_RW(led_current);
128
+static DEVICE_ATTR_RO(max_current);
129129
130130 static struct attribute *lp55xx_led_attrs[] = {
131131 &dev_attr_led_current.attr,
....@@ -133,6 +133,18 @@
133133 NULL,
134134 };
135135 ATTRIBUTE_GROUPS(lp55xx_led);
136
+
137
+static int lp55xx_set_mc_brightness(struct led_classdev *cdev,
138
+ enum led_brightness brightness)
139
+{
140
+ struct led_classdev_mc *mc_dev = lcdev_to_mccdev(cdev);
141
+ struct lp55xx_led *led = mcled_cdev_to_led(mc_dev);
142
+ struct lp55xx_device_config *cfg = led->chip->cfg;
143
+
144
+ led_mc_calc_color_components(&led->mc_cdev, brightness);
145
+ return cfg->multicolor_brightness_fn(led);
146
+
147
+}
136148
137149 static int lp55xx_set_brightness(struct led_classdev *cdev,
138150 enum led_brightness brightness)
....@@ -150,9 +162,12 @@
150162 struct lp55xx_platform_data *pdata = chip->pdata;
151163 struct lp55xx_device_config *cfg = chip->cfg;
152164 struct device *dev = &chip->cl->dev;
153
- char name[32];
154
- int ret;
155165 int max_channel = cfg->max_channel;
166
+ struct mc_subled *mc_led_info;
167
+ struct led_classdev *led_cdev;
168
+ char name[32];
169
+ int i, j = 0;
170
+ int ret;
156171
157172 if (chan >= max_channel) {
158173 dev_err(dev, "invalid channel: %d / %d\n", chan, max_channel);
....@@ -162,20 +177,6 @@
162177 if (pdata->led_config[chan].led_current == 0)
163178 return 0;
164179
165
- led->led_current = pdata->led_config[chan].led_current;
166
- led->max_current = pdata->led_config[chan].max_current;
167
- led->chan_nr = pdata->led_config[chan].chan_nr;
168
- led->cdev.default_trigger = pdata->led_config[chan].default_trigger;
169
-
170
- if (led->chan_nr >= max_channel) {
171
- dev_err(dev, "Use channel numbers between 0 and %d\n",
172
- max_channel - 1);
173
- return -EINVAL;
174
- }
175
-
176
- led->cdev.brightness_set_blocking = lp55xx_set_brightness;
177
- led->cdev.groups = lp55xx_led_groups;
178
-
179180 if (pdata->led_config[chan].name) {
180181 led->cdev.name = pdata->led_config[chan].name;
181182 } else {
....@@ -184,7 +185,47 @@
184185 led->cdev.name = name;
185186 }
186187
187
- ret = led_classdev_register(dev, &led->cdev);
188
+ if (pdata->led_config[chan].num_colors > 1) {
189
+ mc_led_info = devm_kcalloc(dev,
190
+ pdata->led_config[chan].num_colors,
191
+ sizeof(*mc_led_info), GFP_KERNEL);
192
+ if (!mc_led_info)
193
+ return -ENOMEM;
194
+
195
+ led_cdev = &led->mc_cdev.led_cdev;
196
+ led_cdev->name = led->cdev.name;
197
+ led_cdev->brightness_set_blocking = lp55xx_set_mc_brightness;
198
+ led->mc_cdev.num_colors = pdata->led_config[chan].num_colors;
199
+ for (i = 0; i < led->mc_cdev.num_colors; i++) {
200
+ mc_led_info[i].color_index =
201
+ pdata->led_config[chan].color_id[i];
202
+ mc_led_info[i].channel =
203
+ pdata->led_config[chan].output_num[i];
204
+ j++;
205
+ }
206
+
207
+ led->mc_cdev.subled_info = mc_led_info;
208
+ } else {
209
+ led->cdev.brightness_set_blocking = lp55xx_set_brightness;
210
+ }
211
+
212
+ led->cdev.groups = lp55xx_led_groups;
213
+ led->cdev.default_trigger = pdata->led_config[chan].default_trigger;
214
+ led->led_current = pdata->led_config[chan].led_current;
215
+ led->max_current = pdata->led_config[chan].max_current;
216
+ led->chan_nr = pdata->led_config[chan].chan_nr;
217
+
218
+ if (led->chan_nr >= max_channel) {
219
+ dev_err(dev, "Use channel numbers between 0 and %d\n",
220
+ max_channel - 1);
221
+ return -EINVAL;
222
+ }
223
+
224
+ if (pdata->led_config[chan].num_colors > 1)
225
+ ret = devm_led_classdev_multicolor_register(dev, &led->mc_cdev);
226
+ else
227
+ ret = devm_led_classdev_register(dev, &led->cdev);
228
+
188229 if (ret) {
189230 dev_err(dev, "led register err: %d\n", ret);
190231 return ret;
....@@ -228,7 +269,7 @@
228269 GFP_KERNEL, chip, lp55xx_firmware_loaded);
229270 }
230271
231
-static ssize_t lp55xx_show_engine_select(struct device *dev,
272
+static ssize_t select_engine_show(struct device *dev,
232273 struct device_attribute *attr,
233274 char *buf)
234275 {
....@@ -238,7 +279,7 @@
238279 return sprintf(buf, "%d\n", chip->engine_idx);
239280 }
240281
241
-static ssize_t lp55xx_store_engine_select(struct device *dev,
282
+static ssize_t select_engine_store(struct device *dev,
242283 struct device_attribute *attr,
243284 const char *buf, size_t len)
244285 {
....@@ -280,7 +321,7 @@
280321 chip->cfg->run_engine(chip, start);
281322 }
282323
283
-static ssize_t lp55xx_store_engine_run(struct device *dev,
324
+static ssize_t run_engine_store(struct device *dev,
284325 struct device_attribute *attr,
285326 const char *buf, size_t len)
286327 {
....@@ -305,9 +346,8 @@
305346 return len;
306347 }
307348
308
-static DEVICE_ATTR(select_engine, S_IRUGO | S_IWUSR,
309
- lp55xx_show_engine_select, lp55xx_store_engine_select);
310
-static DEVICE_ATTR(run_engine, S_IWUSR, NULL, lp55xx_store_engine_run);
349
+static DEVICE_ATTR_RW(select_engine);
350
+static DEVICE_ATTR_WO(run_engine);
311351
312352 static struct attribute *lp55xx_engine_attributes[] = {
313353 &dev_attr_select_engine.attr,
....@@ -398,18 +438,11 @@
398438 if (!pdata || !cfg)
399439 return -EINVAL;
400440
401
- if (gpio_is_valid(pdata->enable_gpio)) {
402
- ret = devm_gpio_request_one(dev, pdata->enable_gpio,
403
- GPIOF_DIR_OUT, "lp5523_enable");
404
- if (ret < 0) {
405
- dev_err(dev, "could not acquire enable gpio (err=%d)\n",
406
- ret);
407
- goto err;
408
- }
409
-
410
- gpio_set_value(pdata->enable_gpio, 0);
441
+ if (pdata->enable_gpiod) {
442
+ gpiod_set_consumer_name(pdata->enable_gpiod, "LP55xx enable");
443
+ gpiod_set_value(pdata->enable_gpiod, 0);
411444 usleep_range(1000, 2000); /* Keep enable down at least 1ms */
412
- gpio_set_value(pdata->enable_gpio, 1);
445
+ gpiod_set_value(pdata->enable_gpiod, 1);
413446 usleep_range(1000, 2000); /* 500us abs min. */
414447 }
415448
....@@ -450,8 +483,8 @@
450483 if (chip->clk)
451484 clk_disable_unprepare(chip->clk);
452485
453
- if (gpio_is_valid(pdata->enable_gpio))
454
- gpio_set_value(pdata->enable_gpio, 0);
486
+ if (pdata->enable_gpiod)
487
+ gpiod_set_value(pdata->enable_gpiod, 0);
455488 }
456489 EXPORT_SYMBOL_GPL(lp55xx_deinit_device);
457490
....@@ -493,22 +526,9 @@
493526 return 0;
494527
495528 err_init_led:
496
- lp55xx_unregister_leds(led, chip);
497529 return ret;
498530 }
499531 EXPORT_SYMBOL_GPL(lp55xx_register_leds);
500
-
501
-void lp55xx_unregister_leds(struct lp55xx_led *led, struct lp55xx_chip *chip)
502
-{
503
- int i;
504
- struct lp55xx_led *each;
505
-
506
- for (i = 0; i < chip->num_leds; i++) {
507
- each = led + i;
508
- led_classdev_unregister(&each->cdev);
509
- }
510
-}
511
-EXPORT_SYMBOL_GPL(lp55xx_unregister_leds);
512532
513533 int lp55xx_register_sysfs(struct lp55xx_chip *chip)
514534 {
....@@ -541,20 +561,113 @@
541561 }
542562 EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs);
543563
564
+static int lp55xx_parse_common_child(struct device_node *np,
565
+ struct lp55xx_led_config *cfg,
566
+ int led_number, int *chan_nr)
567
+{
568
+ int ret;
569
+
570
+ of_property_read_string(np, "chan-name",
571
+ &cfg[led_number].name);
572
+ of_property_read_u8(np, "led-cur",
573
+ &cfg[led_number].led_current);
574
+ of_property_read_u8(np, "max-cur",
575
+ &cfg[led_number].max_current);
576
+
577
+ ret = of_property_read_u32(np, "reg", chan_nr);
578
+ if (ret)
579
+ return ret;
580
+
581
+ if (*chan_nr < 0 || *chan_nr > cfg->max_channel)
582
+ return -EINVAL;
583
+
584
+ return 0;
585
+}
586
+
587
+static int lp55xx_parse_multi_led_child(struct device_node *child,
588
+ struct lp55xx_led_config *cfg,
589
+ int child_number, int color_number)
590
+{
591
+ int chan_nr, color_id, ret;
592
+
593
+ ret = lp55xx_parse_common_child(child, cfg, child_number, &chan_nr);
594
+ if (ret)
595
+ return ret;
596
+
597
+ ret = of_property_read_u32(child, "color", &color_id);
598
+ if (ret)
599
+ return ret;
600
+
601
+ cfg[child_number].color_id[color_number] = color_id;
602
+ cfg[child_number].output_num[color_number] = chan_nr;
603
+
604
+ return 0;
605
+}
606
+
607
+static int lp55xx_parse_multi_led(struct device_node *np,
608
+ struct lp55xx_led_config *cfg,
609
+ int child_number)
610
+{
611
+ struct device_node *child;
612
+ int num_colors = 0, ret;
613
+
614
+ for_each_available_child_of_node(np, child) {
615
+ ret = lp55xx_parse_multi_led_child(child, cfg, child_number,
616
+ num_colors);
617
+ if (ret) {
618
+ of_node_put(child);
619
+ return ret;
620
+ }
621
+ num_colors++;
622
+ }
623
+
624
+ cfg[child_number].num_colors = num_colors;
625
+
626
+ return 0;
627
+}
628
+
629
+static int lp55xx_parse_logical_led(struct device_node *np,
630
+ struct lp55xx_led_config *cfg,
631
+ int child_number)
632
+{
633
+ int led_color, ret;
634
+ int chan_nr = 0;
635
+
636
+ cfg[child_number].default_trigger =
637
+ of_get_property(np, "linux,default-trigger", NULL);
638
+
639
+ ret = of_property_read_u32(np, "color", &led_color);
640
+ if (ret)
641
+ return ret;
642
+
643
+ if (led_color == LED_COLOR_ID_RGB)
644
+ return lp55xx_parse_multi_led(np, cfg, child_number);
645
+
646
+ ret = lp55xx_parse_common_child(np, cfg, child_number, &chan_nr);
647
+ if (ret < 0)
648
+ return ret;
649
+
650
+ cfg[child_number].chan_nr = chan_nr;
651
+
652
+ return ret;
653
+}
654
+
544655 struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev,
545
- struct device_node *np)
656
+ struct device_node *np,
657
+ struct lp55xx_chip *chip)
546658 {
547659 struct device_node *child;
548660 struct lp55xx_platform_data *pdata;
549661 struct lp55xx_led_config *cfg;
550662 int num_channels;
551663 int i = 0;
664
+ int ret;
552665
553666 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
554667 if (!pdata)
555668 return ERR_PTR(-ENOMEM);
556669
557
- num_channels = of_get_child_count(np);
670
+ num_channels = of_get_available_child_count(np);
558671 if (num_channels == 0) {
559672 dev_err(dev, "no LED channels\n");
560673 return ERR_PTR(-EINVAL);
....@@ -566,23 +679,24 @@
566679
567680 pdata->led_config = &cfg[0];
568681 pdata->num_channels = num_channels;
682
+ cfg->max_channel = chip->cfg->max_channel;
569683
570
- for_each_child_of_node(np, child) {
571
- cfg[i].chan_nr = i;
572
-
573
- of_property_read_string(child, "chan-name", &cfg[i].name);
574
- of_property_read_u8(child, "led-cur", &cfg[i].led_current);
575
- of_property_read_u8(child, "max-cur", &cfg[i].max_current);
576
- cfg[i].default_trigger =
577
- of_get_property(child, "linux,default-trigger", NULL);
578
-
684
+ for_each_available_child_of_node(np, child) {
685
+ ret = lp55xx_parse_logical_led(child, cfg, i);
686
+ if (ret) {
687
+ of_node_put(child);
688
+ return ERR_PTR(-EINVAL);
689
+ }
579690 i++;
580691 }
581692
582693 of_property_read_string(np, "label", &pdata->label);
583694 of_property_read_u8(np, "clock-mode", &pdata->clock_mode);
584695
585
- pdata->enable_gpio = of_get_named_gpio(np, "enable-gpio", 0);
696
+ pdata->enable_gpiod = devm_gpiod_get_optional(dev, "enable",
697
+ GPIOD_ASIS);
698
+ if (IS_ERR(pdata->enable_gpiod))
699
+ return ERR_CAST(pdata->enable_gpiod);
586700
587701 /* LP8501 specific */
588702 of_property_read_u8(np, "pwr-sel", (u8 *)&pdata->pwr_sel);