leds-expresswire.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Shared library for Kinetic's ExpressWire protocol.
  4. * This protocol works by pulsing the ExpressWire IC's control GPIO.
  5. * ktd2692 and ktd2801 are known to use this protocol.
  6. */
  7. #include <linux/bits.h>
  8. #include <linux/delay.h>
  9. #include <linux/export.h>
  10. #include <linux/gpio/consumer.h>
  11. #include <linux/irqflags.h>
  12. #include <linux/types.h>
  13. #include <linux/leds-expresswire.h>
  14. void expresswire_power_off(struct expresswire_common_props *props)
  15. {
  16. gpiod_set_value_cansleep(props->ctrl_gpio, 0);
  17. fsleep(props->timing.poweroff_us);
  18. }
  19. EXPORT_SYMBOL_NS_GPL(expresswire_power_off, "EXPRESSWIRE");
  20. void expresswire_enable(struct expresswire_common_props *props)
  21. {
  22. unsigned long flags;
  23. local_irq_save(flags);
  24. gpiod_set_value(props->ctrl_gpio, 1);
  25. udelay(props->timing.detect_delay_us);
  26. gpiod_set_value(props->ctrl_gpio, 0);
  27. udelay(props->timing.detect_us);
  28. gpiod_set_value(props->ctrl_gpio, 1);
  29. local_irq_restore(flags);
  30. }
  31. EXPORT_SYMBOL_NS_GPL(expresswire_enable, "EXPRESSWIRE");
  32. static void expresswire_start(struct expresswire_common_props *props)
  33. {
  34. gpiod_set_value(props->ctrl_gpio, 1);
  35. udelay(props->timing.data_start_us);
  36. }
  37. static void expresswire_end(struct expresswire_common_props *props)
  38. {
  39. gpiod_set_value(props->ctrl_gpio, 0);
  40. udelay(props->timing.end_of_data_low_us);
  41. gpiod_set_value(props->ctrl_gpio, 1);
  42. udelay(props->timing.end_of_data_high_us);
  43. }
  44. static void expresswire_set_bit(struct expresswire_common_props *props, bool bit)
  45. {
  46. if (bit) {
  47. gpiod_set_value(props->ctrl_gpio, 0);
  48. udelay(props->timing.short_bitset_us);
  49. gpiod_set_value(props->ctrl_gpio, 1);
  50. udelay(props->timing.long_bitset_us);
  51. } else {
  52. gpiod_set_value(props->ctrl_gpio, 0);
  53. udelay(props->timing.long_bitset_us);
  54. gpiod_set_value(props->ctrl_gpio, 1);
  55. udelay(props->timing.short_bitset_us);
  56. }
  57. }
  58. void expresswire_write_u8(struct expresswire_common_props *props, u8 val)
  59. {
  60. unsigned long flags;
  61. local_irq_save(flags);
  62. expresswire_start(props);
  63. for (int i = 7; i >= 0; i--)
  64. expresswire_set_bit(props, val & BIT(i));
  65. expresswire_end(props);
  66. local_irq_restore(flags);
  67. }
  68. EXPORT_SYMBOL_NS_GPL(expresswire_write_u8, "EXPRESSWIRE");