1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2009,2018 Daniel Mack <daniel@zonque.org>
4 #include <linux/kernel.h>
5 #include <linux/platform_device.h>
6 #include <linux/leds.h>
7 #include <linux/delay.h>
8 #include <linux/gpio/consumer.h>
9 #include <linux/slab.h>
10 #include <linux/module.h>
13 #define LED_LT3593_NAME "lt3593"
15 struct lt3593_led_data
{
16 struct led_classdev cdev
;
17 struct gpio_desc
*gpiod
;
20 static int lt3593_led_set(struct led_classdev
*led_cdev
,
21 enum led_brightness value
)
23 struct lt3593_led_data
*led_dat
=
24 container_of(led_cdev
, struct lt3593_led_data
, cdev
);
28 * The LT3593 resets its internal current level register to the maximum
29 * level on the first falling edge on the control pin. Each following
30 * falling edge decreases the current level by 625uA. Up to 32 pulses
31 * can be sent, so the maximum power reduction is 20mA.
32 * After a timeout of 128us, the value is taken from the register and
33 * applied is to the output driver.
37 gpiod_set_value_cansleep(led_dat
->gpiod
, 0);
41 pulses
= 32 - (value
* 32) / 255;
44 gpiod_set_value_cansleep(led_dat
->gpiod
, 0);
46 gpiod_set_value_cansleep(led_dat
->gpiod
, 1);
50 gpiod_set_value_cansleep(led_dat
->gpiod
, 1);
53 gpiod_set_value_cansleep(led_dat
->gpiod
, 0);
55 gpiod_set_value_cansleep(led_dat
->gpiod
, 1);
62 static int lt3593_led_probe(struct platform_device
*pdev
)
64 struct device
*dev
= &pdev
->dev
;
65 struct lt3593_led_data
*led_data
;
66 struct fwnode_handle
*child
;
67 int ret
, state
= LEDS_GPIO_DEFSTATE_OFF
;
68 struct led_init_data init_data
= {};
71 if (!dev_of_node(dev
))
74 led_data
= devm_kzalloc(dev
, sizeof(*led_data
), GFP_KERNEL
);
78 if (device_get_child_node_count(dev
) != 1) {
79 dev_err(dev
, "Device must have exactly one LED sub-node.");
83 led_data
->gpiod
= devm_gpiod_get(dev
, "lltc,ctrl", 0);
84 if (IS_ERR(led_data
->gpiod
))
85 return PTR_ERR(led_data
->gpiod
);
87 child
= device_get_next_child_node(dev
, NULL
);
89 if (!fwnode_property_read_string(child
, "default-state", &tmp
)) {
90 if (!strcmp(tmp
, "on"))
91 state
= LEDS_GPIO_DEFSTATE_ON
;
94 led_data
->cdev
.brightness_set_blocking
= lt3593_led_set
;
95 led_data
->cdev
.brightness
= state
? LED_FULL
: LED_OFF
;
97 init_data
.fwnode
= child
;
98 init_data
.devicename
= LED_LT3593_NAME
;
99 init_data
.default_label
= ":";
101 ret
= devm_led_classdev_register_ext(dev
, &led_data
->cdev
, &init_data
);
103 fwnode_handle_put(child
);
107 platform_set_drvdata(pdev
, led_data
);
112 static const struct of_device_id of_lt3593_leds_match
[] = {
113 { .compatible
= "lltc,lt3593", },
116 MODULE_DEVICE_TABLE(of
, of_lt3593_leds_match
);
118 static struct platform_driver lt3593_led_driver
= {
119 .probe
= lt3593_led_probe
,
121 .name
= "leds-lt3593",
122 .of_match_table
= of_match_ptr(of_lt3593_leds_match
),
126 module_platform_driver(lt3593_led_driver
);
128 MODULE_AUTHOR("Daniel Mack <daniel@zonque.org>");
129 MODULE_DESCRIPTION("LED driver for LT3593 controllers");
130 MODULE_LICENSE("GPL v2");
131 MODULE_ALIAS("platform:leds-lt3593");