leds-lt3593.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (c) 2009,2018 Daniel Mack <[email protected]>
  3. #include <linux/kernel.h>
  4. #include <linux/platform_device.h>
  5. #include <linux/leds.h>
  6. #include <linux/delay.h>
  7. #include <linux/gpio/consumer.h>
  8. #include <linux/slab.h>
  9. #include <linux/mod_devicetable.h>
  10. #include <linux/module.h>
  11. #include <linux/property.h>
  12. #define LED_LT3593_NAME "lt3593"
  13. struct lt3593_led_data {
  14. struct led_classdev cdev;
  15. struct gpio_desc *gpiod;
  16. };
  17. static int lt3593_led_set(struct led_classdev *led_cdev,
  18. enum led_brightness value)
  19. {
  20. struct lt3593_led_data *led_dat =
  21. container_of(led_cdev, struct lt3593_led_data, cdev);
  22. int pulses;
  23. /*
  24. * The LT3593 resets its internal current level register to the maximum
  25. * level on the first falling edge on the control pin. Each following
  26. * falling edge decreases the current level by 625uA. Up to 32 pulses
  27. * can be sent, so the maximum power reduction is 20mA.
  28. * After a timeout of 128us, the value is taken from the register and
  29. * applied is to the output driver.
  30. */
  31. if (value == 0) {
  32. gpiod_set_value_cansleep(led_dat->gpiod, 0);
  33. return 0;
  34. }
  35. pulses = 32 - (value * 32) / 255;
  36. if (pulses == 0) {
  37. gpiod_set_value_cansleep(led_dat->gpiod, 0);
  38. mdelay(1);
  39. gpiod_set_value_cansleep(led_dat->gpiod, 1);
  40. return 0;
  41. }
  42. gpiod_set_value_cansleep(led_dat->gpiod, 1);
  43. while (pulses--) {
  44. gpiod_set_value_cansleep(led_dat->gpiod, 0);
  45. udelay(1);
  46. gpiod_set_value_cansleep(led_dat->gpiod, 1);
  47. udelay(1);
  48. }
  49. return 0;
  50. }
  51. static int lt3593_led_probe(struct platform_device *pdev)
  52. {
  53. struct device *dev = &pdev->dev;
  54. struct lt3593_led_data *led_data;
  55. struct fwnode_handle *child;
  56. int ret, state = LEDS_GPIO_DEFSTATE_OFF;
  57. struct led_init_data init_data = {};
  58. const char *tmp;
  59. led_data = devm_kzalloc(dev, sizeof(*led_data), GFP_KERNEL);
  60. if (!led_data)
  61. return -ENOMEM;
  62. if (device_get_child_node_count(dev) != 1) {
  63. dev_err(dev, "Device must have exactly one LED sub-node.");
  64. return -EINVAL;
  65. }
  66. led_data->gpiod = devm_gpiod_get(dev, "lltc,ctrl", 0);
  67. if (IS_ERR(led_data->gpiod))
  68. return PTR_ERR(led_data->gpiod);
  69. child = device_get_next_child_node(dev, NULL);
  70. if (!fwnode_property_read_string(child, "default-state", &tmp)) {
  71. if (!strcmp(tmp, "on"))
  72. state = LEDS_GPIO_DEFSTATE_ON;
  73. }
  74. led_data->cdev.brightness_set_blocking = lt3593_led_set;
  75. led_data->cdev.brightness = state ? LED_FULL : LED_OFF;
  76. init_data.fwnode = child;
  77. init_data.devicename = LED_LT3593_NAME;
  78. init_data.default_label = ":";
  79. ret = devm_led_classdev_register_ext(dev, &led_data->cdev, &init_data);
  80. fwnode_handle_put(child);
  81. if (ret < 0)
  82. return ret;
  83. platform_set_drvdata(pdev, led_data);
  84. return 0;
  85. }
  86. static const struct of_device_id of_lt3593_leds_match[] = {
  87. { .compatible = "lltc,lt3593", },
  88. {},
  89. };
  90. MODULE_DEVICE_TABLE(of, of_lt3593_leds_match);
  91. static struct platform_driver lt3593_led_driver = {
  92. .probe = lt3593_led_probe,
  93. .driver = {
  94. .name = "leds-lt3593",
  95. .of_match_table = of_lt3593_leds_match,
  96. },
  97. };
  98. module_platform_driver(lt3593_led_driver);
  99. MODULE_AUTHOR("Daniel Mack <[email protected]>");
  100. MODULE_DESCRIPTION("LED driver for LT3593 controllers");
  101. MODULE_LICENSE("GPL v2");
  102. MODULE_ALIAS("platform:leds-lt3593");