From 883e395b2b07ab04f8fe57ac91e63e71dde5d4f6 Mon Sep 17 00:00:00 2001 From: John Klug Date: Tue, 10 Aug 2021 18:21:34 -0500 Subject: Add MTRE support --- io-module/mts_leds.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 io-module/mts_leds.c (limited to 'io-module/mts_leds.c') diff --git a/io-module/mts_leds.c b/io-module/mts_leds.c new file mode 100644 index 0000000..a5cfbbb --- /dev/null +++ b/io-module/mts_leds.c @@ -0,0 +1,146 @@ +/* + * Use the code below to control the brightness of the LEDs using + * Linux LED framework instead of manipulating gpio pins or i2c registers + * directly in the mts-io module. + * + * Usage: + * + * # associate a mts-io sysfs entry with the specific LEDs + * echo led-sig1 > /sys/class/leds/pca955x:0/trigger + * echo led-sig2 > /sys/class/leds/pca955x:1/trigger + * echo led-sig3 > /sys/class/leds/pca955x:2/trigger + * + * # change the brightness + * echo 1 > /sys/device/platform/mts-io/led-sig1 + * echo 1 > /sys/device/platform/mts-io/led-sig2 + * + */ + +struct mts_led { + const char label[32]; /* led name exposed by the mts-io kernel module */ + struct led_trigger *trigger; /* linux led trigger */ +}; + +static struct mts_led *mts_leds = NULL; + +/* + * Find a LED descriptor in mts_leds array by label name + */ +static +struct mts_led *mts_led_by_label(const char *label) +{ + struct mts_led *led = mts_leds; + + while (led && *led->label) { + if (strcmp(led->label, label) == 0) { + return led; + } + led++; + } + + log_error("led with %s label is not found", label); + + return NULL; +} + +/* + * Change brightness for Linux LEDs devices + */ +static +void mts_led_set(const struct mts_led *led, int value) +{ + enum led_brightness brightness = LED_OFF; + + if (value != 0) brightness = LED_FULL; + + if (led->trigger) { + led_trigger_event(led->trigger, brightness); + } + + /* + * Note: there are also led_trigger_blink and led_trigger_blink_oneshot + * functions which can potentially be used + */ +} + +/* + * Blink one shot + */ +static +void mts_led_blink(const struct mts_led *led, + unsigned long *delay_on, unsigned long *delay_off, int invert) +{ + if (led->trigger) { + led_trigger_blink_oneshot(led->trigger, delay_on, delay_off, invert); + } +} + + +/* + * Use the function to get current LED brightness for sysfs entry + */ +static +ssize_t mts_attr_show_led(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", 0); +} + +/* + * Use the function to set LED brightness from sysfs entry + */ +static +ssize_t mts_attr_store_led(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int value; + + const struct mts_led *led = mts_led_by_label(attr->attr.name); + + if (!led) { + return -ENODEV; + } + + if (sscanf(buf, "%i", &value) != 1) { + return -EINVAL; + } + + mts_led_set(led, value); + + return count; +} + +/* + * Register a LED trigger for each LED declared in the mts_leds array + * Use in mts-io startup code. + */ +static +void mts_leds_register(void) +{ + struct mts_led *led = mts_leds; + + while (led && *led->label) { + log_info("Registering %s led trigger", led->label); + led_trigger_register_simple(led->label, &led->trigger); + led++; + } +} + +/* + * Unregister all registered LED triggers. + * Use in mts-io cleanup code. + */ +static +void mts_leds_unregister(void) +{ + struct mts_led *led = mts_leds; + + while (led && *led->label) { + log_info("Unregistering %s led trigger", led->label); + if (led->trigger) { + led_trigger_unregister_simple(led->trigger); + led->trigger = NULL; + } + led++; + } +} -- cgit v1.2.3