platform1.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/of.h>
  4. #include <linux/slab.h>
  5. #include <linux/platform_device.h>
  6. #include <linux/leds.h>
  7. struct gpio_led_data {
  8. struct led_classdev cdev; // LED 的类设备结构
  9. int gpio; // GPIO 引脚
  10. };
  11. struct gpio_leds_priv {
  12. struct gpio_led_data *leds; // 存储 LED 数据
  13. int num_leds; // LED 数量
  14. };
  15. static int gpio_led_probe(struct platform_device *pdev)
  16. {
  17. struct gpio_leds_priv *priv;
  18. int ret;
  19. // 为 priv 分配内存
  20. priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
  21. if (!priv)
  22. return -ENOMEM;
  23. priv->num_leds = /* 从设备树或其他来源获取 LED 数量 */;
  24. priv->leds = devm_kcalloc(&pdev->dev, priv->num_leds, sizeof(*priv->leds), GFP_KERNEL);
  25. if (!priv->leds)
  26. return -ENOMEM;
  27. // 初始化每个 LED
  28. for (int i = 0; i < priv->num_leds; i++) {
  29. priv->leds[i].gpio = /* 获取 GPIO 引脚 */;
  30. priv->leds[i].cdev.name = /* LED 名称 */;
  31. priv->leds[i].cdev.brightness = LED_OFF;
  32. priv->leds[i].cdev.max_brightness = LED_FULL;
  33. // 注册 LED
  34. ret = led_classdev_register(&pdev->dev, &priv->leds[i].cdev);
  35. if (ret) {
  36. dev_err(&pdev->dev, "Failed to register LED %s\n", priv->leds[i].cdev.name);
  37. goto error;
  38. }
  39. }
  40. platform_set_drvdata(pdev, priv); // 存储私有数据
  41. return 0;
  42. error:
  43. // 清理已注册的 LED
  44. for (int j = 0; j < i; j++) {
  45. led_classdev_unregister(&priv->leds[j].cdev);
  46. }
  47. return ret;
  48. }
  49. static void gpio_led_shutdown(struct platform_device *pdev)
  50. {
  51. struct gpio_leds_priv *priv = platform_get_drvdata(pdev);
  52. int i;
  53. for (i = 0; i < priv->num_leds; i++) {
  54. struct gpio_led_data *led = &priv->leds[i];
  55. if (!(led->cdev.flags & LED_RETAIN_AT_SHUTDOWN))
  56. gpio_led_set(&led->cdev, LED_OFF);
  57. }
  58. }
  59. static const struct of_device_id of_gpio_leds_match[] = {
  60. { .compatible = "gpio-leds", },
  61. {}
  62. };
  63. MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
  64. static struct platform_driver gpio_led_driver = {
  65. .probe = gpio_led_probe,
  66. .shutdown = gpio_led_shutdown,
  67. .driver = {
  68. .name = "leds-gpio",
  69. .of_match_table = of_gpio_leds_match,
  70. },
  71. };
  72. module_platform_driver(gpio_led_driver);
  73. MODULE_LICENSE("GPL");
  74. MODULE_AUTHOR("John Madieu <john.madieu@gmail.com>");
  75. MODULE_DESCRIPTION("Linux kernel module skeleton for GPIO LEDs");