backlight-gpio.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-02-25 GuEe-GUI the first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #define DBG_TAG "backlight.gpio"
  14. #define DBG_LVL DBG_INFO
  15. #include <rtdbg.h>
  16. struct gpio_backlight
  17. {
  18. struct rt_backlight_device parent;
  19. rt_base_t pin;
  20. rt_uint8_t active_val;
  21. };
  22. #define raw_to_gpio_backlight(raw) rt_container_of(raw, struct gpio_backlight, parent)
  23. static rt_err_t gpio_backlight_update_status(struct rt_backlight_device *bl)
  24. {
  25. rt_uint8_t brightness;
  26. struct gpio_backlight *gbl = raw_to_gpio_backlight(bl);
  27. rt_pin_mode(gbl->pin, PIN_MODE_OUTPUT);
  28. brightness = rt_backlight_power_brightness(bl);
  29. if (!gbl->active_val)
  30. {
  31. brightness = !brightness;
  32. }
  33. rt_pin_write(gbl->pin, brightness);
  34. return RT_EOK;
  35. }
  36. static struct rt_backlight_ops gpio_backlight_ops =
  37. {
  38. .update_status = gpio_backlight_update_status,
  39. };
  40. static rt_err_t gpio_backlight_probe(struct rt_platform_device *pdev)
  41. {
  42. rt_err_t err;
  43. rt_bool_t def_value;
  44. struct rt_device *dev = &pdev->parent;
  45. struct gpio_backlight *gbl = rt_calloc(1, sizeof(*gbl));
  46. if (!gbl)
  47. {
  48. return -RT_ENOMEM;
  49. }
  50. def_value = rt_dm_dev_prop_read_bool(dev, "default-on");
  51. gbl->pin = rt_pin_get_named_pin(dev, RT_NULL, 0, RT_NULL, &gbl->active_val);
  52. if (gbl->pin < 0)
  53. {
  54. err = gbl->pin;
  55. goto _fail;
  56. }
  57. /* Set the initial power state */
  58. if (!dev->ofw_node || !rt_dm_dev_prop_read_bool(dev, "phandle"))
  59. {
  60. gbl->parent.props.power = def_value ?
  61. RT_BACKLIGHT_POWER_UNBLANK : RT_BACKLIGHT_POWER_POWERDOWN;
  62. }
  63. else if (rt_pin_read(gbl->pin) != gbl->active_val)
  64. {
  65. gbl->parent.props.power = RT_BACKLIGHT_POWER_POWERDOWN;
  66. }
  67. else
  68. {
  69. gbl->parent.props.power = RT_BACKLIGHT_POWER_UNBLANK;
  70. }
  71. gbl->parent.props.max_brightness = 1;
  72. gbl->parent.ops = &gpio_backlight_ops;
  73. if ((err = rt_backlight_register(&gbl->parent)))
  74. {
  75. goto _fail;
  76. }
  77. rt_pin_mode(gbl->pin, PIN_MODE_OUTPUT);
  78. rt_backlight_set_brightness(&gbl->parent, 1);
  79. return RT_EOK;
  80. _fail:
  81. rt_free(gbl);
  82. return err;
  83. }
  84. static rt_err_t gpio_backlight_remove(struct rt_platform_device *pdev)
  85. {
  86. struct gpio_backlight *gbl = pdev->parent.user_data;
  87. rt_backlight_unregister(&gbl->parent);
  88. rt_free(gbl);
  89. return RT_EOK;
  90. }
  91. static const struct rt_ofw_node_id gpio_backlight_ofw_ids[] =
  92. {
  93. { .compatible = "gpio-backlight" },
  94. { /* sentinel */ }
  95. };
  96. static struct rt_platform_driver gpio_backlight_driver =
  97. {
  98. .name = "gpio-backlight",
  99. .ids = gpio_backlight_ofw_ids,
  100. .probe = gpio_backlight_probe,
  101. .remove = gpio_backlight_remove,
  102. };
  103. RT_PLATFORM_DRIVER_EXPORT(gpio_backlight_driver);