leds.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * LED support code, ripped out of arch/arm/kernel/time.c
  3. *
  4. * Copyright (C) 1994-2001 Russell King
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/init.h>
  12. #include <linux/sysdev.h>
  13. #include <asm/leds.h>
  14. static void dummy_leds_event(led_event_t evt)
  15. {
  16. }
  17. void (*leds_event)(led_event_t) = dummy_leds_event;
  18. struct leds_evt_name {
  19. const char name[8];
  20. int on;
  21. int off;
  22. };
  23. static const struct leds_evt_name evt_names[] = {
  24. { "amber", led_amber_on, led_amber_off },
  25. { "blue", led_blue_on, led_blue_off },
  26. { "green", led_green_on, led_green_off },
  27. { "red", led_red_on, led_red_off },
  28. };
  29. static ssize_t leds_store(struct sys_device *dev,
  30. struct sysdev_attribute *attr,
  31. const char *buf, size_t size)
  32. {
  33. int ret = -EINVAL, len = strcspn(buf, " ");
  34. if (len > 0 && buf[len] == '\0')
  35. len--;
  36. if (strncmp(buf, "claim", len) == 0) {
  37. leds_event(led_claim);
  38. ret = size;
  39. } else if (strncmp(buf, "release", len) == 0) {
  40. leds_event(led_release);
  41. ret = size;
  42. } else {
  43. int i;
  44. for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
  45. if (strlen(evt_names[i].name) != len ||
  46. strncmp(buf, evt_names[i].name, len) != 0)
  47. continue;
  48. if (strncmp(buf+len, " on", 3) == 0) {
  49. leds_event(evt_names[i].on);
  50. ret = size;
  51. } else if (strncmp(buf+len, " off", 4) == 0) {
  52. leds_event(evt_names[i].off);
  53. ret = size;
  54. }
  55. break;
  56. }
  57. }
  58. return ret;
  59. }
  60. static SYSDEV_ATTR(event, 0200, NULL, leds_store);
  61. static int leds_suspend(struct sys_device *dev, pm_message_t state)
  62. {
  63. leds_event(led_stop);
  64. return 0;
  65. }
  66. static int leds_resume(struct sys_device *dev)
  67. {
  68. leds_event(led_start);
  69. return 0;
  70. }
  71. static int leds_shutdown(struct sys_device *dev)
  72. {
  73. leds_event(led_halted);
  74. return 0;
  75. }
  76. static struct sysdev_class leds_sysclass = {
  77. .name = "leds",
  78. .shutdown = leds_shutdown,
  79. .suspend = leds_suspend,
  80. .resume = leds_resume,
  81. };
  82. static struct sys_device leds_device = {
  83. .id = 0,
  84. .cls = &leds_sysclass,
  85. };
  86. static int __init leds_init(void)
  87. {
  88. int ret;
  89. ret = sysdev_class_register(&leds_sysclass);
  90. if (ret == 0)
  91. ret = sysdev_register(&leds_device);
  92. if (ret == 0)
  93. ret = sysdev_create_file(&leds_device, &attr_event);
  94. return ret;
  95. }
  96. device_initcall(leds_init);
  97. EXPORT_SYMBOL(leds_event);