Skip to content

Commit

Permalink
leds: triggers: add invert to heartbeat
Browse files Browse the repository at this point in the history
This patch adds possibility to invert heartbeat blinking.
The inverted LED is more time ON then OFF. It's because it looks
better when the heartbeat LED is next to other LED which is most
time ON. The invert value is exported same way via sysfs in file
invert like oneshot. I get inspiration from this trigger.

Signed-off-by: Jiri Prchal <jiri.prchal@aksignal.cz>
Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
  • Loading branch information
Jiri Prchal authored and Jacek Anaszewski committed Nov 3, 2015
1 parent 757b06a commit 1c7b9d0
Showing 1 changed file with 45 additions and 2 deletions.
47 changes: 45 additions & 2 deletions drivers/leds/trigger/ledtrig-heartbeat.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct heartbeat_trig_data {
unsigned int phase;
unsigned int period;
struct timer_list timer;
unsigned int invert;
};

static void led_heartbeat_function(unsigned long data)
Expand Down Expand Up @@ -56,37 +57,78 @@ static void led_heartbeat_function(unsigned long data)
msecs_to_jiffies(heartbeat_data->period);
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
brightness = led_cdev->max_brightness;
if (!heartbeat_data->invert)
brightness = led_cdev->max_brightness;
break;
case 1:
delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
heartbeat_data->phase++;
if (heartbeat_data->invert)
brightness = led_cdev->max_brightness;
break;
case 2:
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
brightness = led_cdev->max_brightness;
if (!heartbeat_data->invert)
brightness = led_cdev->max_brightness;
break;
default:
delay = heartbeat_data->period - heartbeat_data->period / 4 -
msecs_to_jiffies(70);
heartbeat_data->phase = 0;
if (heartbeat_data->invert)
brightness = led_cdev->max_brightness;
break;
}

led_set_brightness_async(led_cdev, brightness);
mod_timer(&heartbeat_data->timer, jiffies + delay);
}

static ssize_t led_invert_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;

return sprintf(buf, "%u\n", heartbeat_data->invert);
}

static ssize_t led_invert_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data;
unsigned long state;
int ret;

ret = kstrtoul(buf, 0, &state);
if (ret)
return ret;

heartbeat_data->invert = !!state;

return size;
}

static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store);

static void heartbeat_trig_activate(struct led_classdev *led_cdev)
{
struct heartbeat_trig_data *heartbeat_data;
int rc;

heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL);
if (!heartbeat_data)
return;

led_cdev->trigger_data = heartbeat_data;
rc = device_create_file(led_cdev->dev, &dev_attr_invert);
if (rc) {
kfree(led_cdev->trigger_data);
return;
}

setup_timer(&heartbeat_data->timer,
led_heartbeat_function, (unsigned long) led_cdev);
heartbeat_data->phase = 0;
Expand All @@ -100,6 +142,7 @@ static void heartbeat_trig_deactivate(struct led_classdev *led_cdev)

if (led_cdev->activated) {
del_timer_sync(&heartbeat_data->timer);
device_remove_file(led_cdev->dev, &dev_attr_invert);
kfree(heartbeat_data);
led_cdev->activated = false;
}
Expand Down

0 comments on commit 1c7b9d0

Please sign in to comment.