root/drivers/leds/trigger/ledtrig-oneshot.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. led_shot
  2. led_invert_show
  3. led_invert_store
  4. led_delay_on_show
  5. led_delay_on_store
  6. led_delay_off_show
  7. led_delay_off_store
  8. pattern_init
  9. oneshot_trig_activate
  10. oneshot_trig_deactivate

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * One-shot LED Trigger
   4  *
   5  * Copyright 2012, Fabio Baltieri <fabio.baltieri@gmail.com>
   6  *
   7  * Based on ledtrig-timer.c by Richard Purdie <rpurdie@openedhand.com>
   8  */
   9 
  10 #include <linux/module.h>
  11 #include <linux/kernel.h>
  12 #include <linux/init.h>
  13 #include <linux/device.h>
  14 #include <linux/ctype.h>
  15 #include <linux/slab.h>
  16 #include <linux/leds.h>
  17 #include "../leds.h"
  18 
  19 #define DEFAULT_DELAY 100
  20 
  21 struct oneshot_trig_data {
  22         unsigned int invert;
  23 };
  24 
  25 static ssize_t led_shot(struct device *dev,
  26                 struct device_attribute *attr, const char *buf, size_t size)
  27 {
  28         struct led_classdev *led_cdev = led_trigger_get_led(dev);
  29         struct oneshot_trig_data *oneshot_data = led_trigger_get_drvdata(dev);
  30 
  31         led_blink_set_oneshot(led_cdev,
  32                         &led_cdev->blink_delay_on, &led_cdev->blink_delay_off,
  33                         oneshot_data->invert);
  34 
  35         /* content is ignored */
  36         return size;
  37 }
  38 static ssize_t led_invert_show(struct device *dev,
  39                 struct device_attribute *attr, char *buf)
  40 {
  41         struct oneshot_trig_data *oneshot_data = led_trigger_get_drvdata(dev);
  42 
  43         return sprintf(buf, "%u\n", oneshot_data->invert);
  44 }
  45 
  46 static ssize_t led_invert_store(struct device *dev,
  47                 struct device_attribute *attr, const char *buf, size_t size)
  48 {
  49         struct led_classdev *led_cdev = led_trigger_get_led(dev);
  50         struct oneshot_trig_data *oneshot_data = led_trigger_get_drvdata(dev);
  51         unsigned long state;
  52         int ret;
  53 
  54         ret = kstrtoul(buf, 0, &state);
  55         if (ret)
  56                 return ret;
  57 
  58         oneshot_data->invert = !!state;
  59 
  60         if (oneshot_data->invert)
  61                 led_set_brightness_nosleep(led_cdev, LED_FULL);
  62         else
  63                 led_set_brightness_nosleep(led_cdev, LED_OFF);
  64 
  65         return size;
  66 }
  67 
  68 static ssize_t led_delay_on_show(struct device *dev,
  69                 struct device_attribute *attr, char *buf)
  70 {
  71         struct led_classdev *led_cdev = led_trigger_get_led(dev);
  72 
  73         return sprintf(buf, "%lu\n", led_cdev->blink_delay_on);
  74 }
  75 
  76 static ssize_t led_delay_on_store(struct device *dev,
  77                 struct device_attribute *attr, const char *buf, size_t size)
  78 {
  79         struct led_classdev *led_cdev = led_trigger_get_led(dev);
  80         unsigned long state;
  81         int ret;
  82 
  83         ret = kstrtoul(buf, 0, &state);
  84         if (ret)
  85                 return ret;
  86 
  87         led_cdev->blink_delay_on = state;
  88 
  89         return size;
  90 }
  91 
  92 static ssize_t led_delay_off_show(struct device *dev,
  93                 struct device_attribute *attr, char *buf)
  94 {
  95         struct led_classdev *led_cdev = led_trigger_get_led(dev);
  96 
  97         return sprintf(buf, "%lu\n", led_cdev->blink_delay_off);
  98 }
  99 
 100 static ssize_t led_delay_off_store(struct device *dev,
 101                 struct device_attribute *attr, const char *buf, size_t size)
 102 {
 103         struct led_classdev *led_cdev = led_trigger_get_led(dev);
 104         unsigned long state;
 105         int ret;
 106 
 107         ret = kstrtoul(buf, 0, &state);
 108         if (ret)
 109                 return ret;
 110 
 111         led_cdev->blink_delay_off = state;
 112 
 113         return size;
 114 }
 115 
 116 static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store);
 117 static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store);
 118 static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store);
 119 static DEVICE_ATTR(shot, 0200, NULL, led_shot);
 120 
 121 static struct attribute *oneshot_trig_attrs[] = {
 122         &dev_attr_delay_on.attr,
 123         &dev_attr_delay_off.attr,
 124         &dev_attr_invert.attr,
 125         &dev_attr_shot.attr,
 126         NULL
 127 };
 128 ATTRIBUTE_GROUPS(oneshot_trig);
 129 
 130 static void pattern_init(struct led_classdev *led_cdev)
 131 {
 132         u32 *pattern;
 133         unsigned int size = 0;
 134 
 135         pattern = led_get_default_pattern(led_cdev, &size);
 136         if (!pattern)
 137                 goto out_default;
 138 
 139         if (size != 2) {
 140                 dev_warn(led_cdev->dev,
 141                          "Expected 2 but got %u values for delays pattern\n",
 142                          size);
 143                 goto out_default;
 144         }
 145 
 146         led_cdev->blink_delay_on = pattern[0];
 147         led_cdev->blink_delay_off = pattern[1];
 148         kfree(pattern);
 149 
 150         return;
 151 
 152 out_default:
 153         kfree(pattern);
 154         led_cdev->blink_delay_on = DEFAULT_DELAY;
 155         led_cdev->blink_delay_off = DEFAULT_DELAY;
 156 }
 157 
 158 static int oneshot_trig_activate(struct led_classdev *led_cdev)
 159 {
 160         struct oneshot_trig_data *oneshot_data;
 161 
 162         oneshot_data = kzalloc(sizeof(*oneshot_data), GFP_KERNEL);
 163         if (!oneshot_data)
 164                 return -ENOMEM;
 165 
 166         led_set_trigger_data(led_cdev, oneshot_data);
 167 
 168         if (led_cdev->flags & LED_INIT_DEFAULT_TRIGGER) {
 169                 pattern_init(led_cdev);
 170                 /*
 171                  * Mark as initialized even on pattern_init() error because
 172                  * any consecutive call to it would produce the same error.
 173                  */
 174                 led_cdev->flags &= ~LED_INIT_DEFAULT_TRIGGER;
 175         }
 176 
 177         return 0;
 178 }
 179 
 180 static void oneshot_trig_deactivate(struct led_classdev *led_cdev)
 181 {
 182         struct oneshot_trig_data *oneshot_data = led_get_trigger_data(led_cdev);
 183 
 184         kfree(oneshot_data);
 185 
 186         /* Stop blinking */
 187         led_set_brightness(led_cdev, LED_OFF);
 188 }
 189 
 190 static struct led_trigger oneshot_led_trigger = {
 191         .name     = "oneshot",
 192         .activate = oneshot_trig_activate,
 193         .deactivate = oneshot_trig_deactivate,
 194         .groups = oneshot_trig_groups,
 195 };
 196 module_led_trigger(oneshot_led_trigger);
 197 
 198 MODULE_AUTHOR("Fabio Baltieri <fabio.baltieri@gmail.com>");
 199 MODULE_DESCRIPTION("One-shot LED trigger");
 200 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */