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.h>
9 #include <linux/gpio/consumer.h>
10 #include <linux/slab.h>
11 #include <linux/module.h>
13 #include <uapi/linux/uleds.h>
15 struct lt3593_led_data
{
16 char name
[LED_MAX_NAME_SIZE
];
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 struct lt3593_led_data
*lt3593_led_probe_pdata(struct device
*dev
)
65 struct gpio_led_platform_data
*pdata
= dev_get_platdata(dev
);
66 const struct gpio_led
*template = &pdata
->leds
[0];
67 struct lt3593_led_data
*led_data
;
70 if (pdata
->num_leds
!= 1)
71 return ERR_PTR(-EINVAL
);
73 led_data
= devm_kzalloc(dev
, sizeof(*led_data
), GFP_KERNEL
);
75 return ERR_PTR(-ENOMEM
);
77 led_data
->cdev
.name
= template->name
;
78 led_data
->cdev
.default_trigger
= template->default_trigger
;
79 led_data
->cdev
.brightness_set_blocking
= lt3593_led_set
;
81 state
= (template->default_state
== LEDS_GPIO_DEFSTATE_ON
);
82 led_data
->cdev
.brightness
= state
? LED_FULL
: LED_OFF
;
84 if (!template->retain_state_suspended
)
85 led_data
->cdev
.flags
|= LED_CORE_SUSPENDRESUME
;
87 ret
= devm_gpio_request_one(dev
, template->gpio
, state
?
88 GPIOF_OUT_INIT_HIGH
: GPIOF_OUT_INIT_LOW
,
93 led_data
->gpiod
= gpio_to_desc(template->gpio
);
95 return ERR_PTR(-EPROBE_DEFER
);
97 ret
= devm_led_classdev_register(dev
, &led_data
->cdev
);
101 dev_info(dev
, "registered LT3593 LED '%s' at GPIO %d\n",
102 template->name
, template->gpio
);
107 static int lt3593_led_probe(struct platform_device
*pdev
)
109 struct device
*dev
= &pdev
->dev
;
110 struct lt3593_led_data
*led_data
;
111 struct fwnode_handle
*child
;
112 int ret
, state
= LEDS_GPIO_DEFSTATE_OFF
;
113 enum gpiod_flags flags
= GPIOD_OUT_LOW
;
116 if (dev_get_platdata(dev
)) {
117 led_data
= lt3593_led_probe_pdata(dev
);
118 if (IS_ERR(led_data
))
119 return PTR_ERR(led_data
);
127 led_data
= devm_kzalloc(dev
, sizeof(*led_data
), GFP_KERNEL
);
131 if (device_get_child_node_count(dev
) != 1) {
132 dev_err(dev
, "Device must have exactly one LED sub-node.");
136 led_data
->gpiod
= devm_gpiod_get(dev
, "lltc,ctrl", 0);
137 if (IS_ERR(led_data
->gpiod
))
138 return PTR_ERR(led_data
->gpiod
);
140 child
= device_get_next_child_node(dev
, NULL
);
142 ret
= fwnode_property_read_string(child
, "label", &tmp
);
144 snprintf(led_data
->name
, sizeof(led_data
->name
),
147 snprintf(led_data
->name
, sizeof(led_data
->name
),
150 fwnode_property_read_string(child
, "linux,default-trigger",
151 &led_data
->cdev
.default_trigger
);
153 if (!fwnode_property_read_string(child
, "default-state", &tmp
)) {
154 if (!strcmp(tmp
, "keep")) {
155 state
= LEDS_GPIO_DEFSTATE_KEEP
;
157 } else if (!strcmp(tmp
, "on")) {
158 state
= LEDS_GPIO_DEFSTATE_ON
;
159 flags
= GPIOD_OUT_HIGH
;
163 led_data
->cdev
.name
= led_data
->name
;
164 led_data
->cdev
.brightness_set_blocking
= lt3593_led_set
;
165 led_data
->cdev
.brightness
= state
? LED_FULL
: LED_OFF
;
167 ret
= devm_led_classdev_register(dev
, &led_data
->cdev
);
169 fwnode_handle_put(child
);
173 led_data
->cdev
.dev
->of_node
= dev
->of_node
;
176 platform_set_drvdata(pdev
, led_data
);
182 static const struct of_device_id of_lt3593_leds_match
[] = {
183 { .compatible
= "lltc,lt3593", },
186 MODULE_DEVICE_TABLE(of
, of_lt3593_leds_match
);
189 static struct platform_driver lt3593_led_driver
= {
190 .probe
= lt3593_led_probe
,
192 .name
= "leds-lt3593",
193 .of_match_table
= of_match_ptr(of_lt3593_leds_match
),
197 module_platform_driver(lt3593_led_driver
);
199 MODULE_AUTHOR("Daniel Mack <daniel@zonque.org>");
200 MODULE_DESCRIPTION("LED driver for LT3593 controllers");
201 MODULE_LICENSE("GPL v2");
202 MODULE_ALIAS("platform:leds-lt3593");