0001
0002
0003
0004 #include <linux/kernel.h>
0005 #include <linux/platform_device.h>
0006 #include <linux/leds.h>
0007 #include <linux/delay.h>
0008 #include <linux/gpio/consumer.h>
0009 #include <linux/slab.h>
0010 #include <linux/mod_devicetable.h>
0011 #include <linux/module.h>
0012 #include <linux/property.h>
0013
0014 #define LED_LT3593_NAME "lt3593"
0015
0016 struct lt3593_led_data {
0017 struct led_classdev cdev;
0018 struct gpio_desc *gpiod;
0019 };
0020
0021 static int lt3593_led_set(struct led_classdev *led_cdev,
0022 enum led_brightness value)
0023 {
0024 struct lt3593_led_data *led_dat =
0025 container_of(led_cdev, struct lt3593_led_data, cdev);
0026 int pulses;
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 if (value == 0) {
0038 gpiod_set_value_cansleep(led_dat->gpiod, 0);
0039 return 0;
0040 }
0041
0042 pulses = 32 - (value * 32) / 255;
0043
0044 if (pulses == 0) {
0045 gpiod_set_value_cansleep(led_dat->gpiod, 0);
0046 mdelay(1);
0047 gpiod_set_value_cansleep(led_dat->gpiod, 1);
0048 return 0;
0049 }
0050
0051 gpiod_set_value_cansleep(led_dat->gpiod, 1);
0052
0053 while (pulses--) {
0054 gpiod_set_value_cansleep(led_dat->gpiod, 0);
0055 udelay(1);
0056 gpiod_set_value_cansleep(led_dat->gpiod, 1);
0057 udelay(1);
0058 }
0059
0060 return 0;
0061 }
0062
0063 static int lt3593_led_probe(struct platform_device *pdev)
0064 {
0065 struct device *dev = &pdev->dev;
0066 struct lt3593_led_data *led_data;
0067 struct fwnode_handle *child;
0068 int ret, state = LEDS_GPIO_DEFSTATE_OFF;
0069 struct led_init_data init_data = {};
0070 const char *tmp;
0071
0072 led_data = devm_kzalloc(dev, sizeof(*led_data), GFP_KERNEL);
0073 if (!led_data)
0074 return -ENOMEM;
0075
0076 if (device_get_child_node_count(dev) != 1) {
0077 dev_err(dev, "Device must have exactly one LED sub-node.");
0078 return -EINVAL;
0079 }
0080
0081 led_data->gpiod = devm_gpiod_get(dev, "lltc,ctrl", 0);
0082 if (IS_ERR(led_data->gpiod))
0083 return PTR_ERR(led_data->gpiod);
0084
0085 child = device_get_next_child_node(dev, NULL);
0086
0087 if (!fwnode_property_read_string(child, "default-state", &tmp)) {
0088 if (!strcmp(tmp, "on"))
0089 state = LEDS_GPIO_DEFSTATE_ON;
0090 }
0091
0092 led_data->cdev.brightness_set_blocking = lt3593_led_set;
0093 led_data->cdev.brightness = state ? LED_FULL : LED_OFF;
0094
0095 init_data.fwnode = child;
0096 init_data.devicename = LED_LT3593_NAME;
0097 init_data.default_label = ":";
0098
0099 ret = devm_led_classdev_register_ext(dev, &led_data->cdev, &init_data);
0100 fwnode_handle_put(child);
0101 if (ret < 0)
0102 return ret;
0103
0104 platform_set_drvdata(pdev, led_data);
0105
0106 return 0;
0107 }
0108
0109 static const struct of_device_id of_lt3593_leds_match[] = {
0110 { .compatible = "lltc,lt3593", },
0111 {},
0112 };
0113 MODULE_DEVICE_TABLE(of, of_lt3593_leds_match);
0114
0115 static struct platform_driver lt3593_led_driver = {
0116 .probe = lt3593_led_probe,
0117 .driver = {
0118 .name = "leds-lt3593",
0119 .of_match_table = of_lt3593_leds_match,
0120 },
0121 };
0122
0123 module_platform_driver(lt3593_led_driver);
0124
0125 MODULE_AUTHOR("Daniel Mack <daniel@zonque.org>");
0126 MODULE_DESCRIPTION("LED driver for LT3593 controllers");
0127 MODULE_LICENSE("GPL v2");
0128 MODULE_ALIAS("platform:leds-lt3593");