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/mod_devicetable.h>
11 #include <linux/module.h>
12 #include <linux/property.h>
14 #define LED_LT3593_NAME "lt3593"
16 struct lt3593_led_data
{
17 struct led_classdev cdev
;
18 struct gpio_desc
*gpiod
;
21 static int lt3593_led_set(struct led_classdev
*led_cdev
,
22 enum led_brightness value
)
24 struct lt3593_led_data
*led_dat
=
25 container_of(led_cdev
, struct lt3593_led_data
, cdev
);
29 * The LT3593 resets its internal current level register to the maximum
30 * level on the first falling edge on the control pin. Each following
31 * falling edge decreases the current level by 625uA. Up to 32 pulses
32 * can be sent, so the maximum power reduction is 20mA.
33 * After a timeout of 128us, the value is taken from the register and
34 * applied is to the output driver.
38 gpiod_set_value_cansleep(led_dat
->gpiod
, 0);
42 pulses
= 32 - (value
* 32) / 255;
45 gpiod_set_value_cansleep(led_dat
->gpiod
, 0);
47 gpiod_set_value_cansleep(led_dat
->gpiod
, 1);
51 gpiod_set_value_cansleep(led_dat
->gpiod
, 1);
54 gpiod_set_value_cansleep(led_dat
->gpiod
, 0);
56 gpiod_set_value_cansleep(led_dat
->gpiod
, 1);
63 static int lt3593_led_probe(struct platform_device
*pdev
)
65 struct device
*dev
= &pdev
->dev
;
66 struct lt3593_led_data
*led_data
;
67 struct fwnode_handle
*child
;
68 int ret
, state
= LEDS_GPIO_DEFSTATE_OFF
;
69 struct led_init_data init_data
= {};
72 led_data
= devm_kzalloc(dev
, sizeof(*led_data
), GFP_KERNEL
);
76 if (device_get_child_node_count(dev
) != 1) {
77 dev_err(dev
, "Device must have exactly one LED sub-node.");
81 led_data
->gpiod
= devm_gpiod_get(dev
, "lltc,ctrl", 0);
82 if (IS_ERR(led_data
->gpiod
))
83 return PTR_ERR(led_data
->gpiod
);
85 child
= device_get_next_child_node(dev
, NULL
);
87 if (!fwnode_property_read_string(child
, "default-state", &tmp
)) {
88 if (!strcmp(tmp
, "on"))
89 state
= LEDS_GPIO_DEFSTATE_ON
;
92 led_data
->cdev
.brightness_set_blocking
= lt3593_led_set
;
93 led_data
->cdev
.brightness
= state
? LED_FULL
: LED_OFF
;
95 init_data
.fwnode
= child
;
96 init_data
.devicename
= LED_LT3593_NAME
;
97 init_data
.default_label
= ":";
99 ret
= devm_led_classdev_register_ext(dev
, &led_data
->cdev
, &init_data
);
100 fwnode_handle_put(child
);
104 platform_set_drvdata(pdev
, led_data
);
109 static const struct of_device_id of_lt3593_leds_match
[] = {
110 { .compatible
= "lltc,lt3593", },
113 MODULE_DEVICE_TABLE(of
, of_lt3593_leds_match
);
115 static struct platform_driver lt3593_led_driver
= {
116 .probe
= lt3593_led_probe
,
118 .name
= "leds-lt3593",
119 .of_match_table
= of_lt3593_leds_match
,
123 module_platform_driver(lt3593_led_driver
);
125 MODULE_AUTHOR("Daniel Mack <daniel@zonque.org>");
126 MODULE_DESCRIPTION("LED driver for LT3593 controllers");
127 MODULE_LICENSE("GPL v2");
128 MODULE_ALIAS("platform:leds-lt3593");