summaryrefslogtreecommitdiff
path: root/io-module/mts_leds.c
diff options
context:
space:
mode:
Diffstat (limited to 'io-module/mts_leds.c')
-rw-r--r--io-module/mts_leds.c146
1 files changed, 146 insertions, 0 deletions
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++;
+ }
+}