Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

leds: triggers: add invert to heartbeat

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>

authored by

Jiri Prchal and committed by
Jacek Anaszewski
1c7b9d0e 757b06ae

+45 -2
+45 -2
drivers/leds/trigger/ledtrig-heartbeat.c
··· 27 27 unsigned int phase; 28 28 unsigned int period; 29 29 struct timer_list timer; 30 + unsigned int invert; 30 31 }; 31 32 32 33 static void led_heartbeat_function(unsigned long data) ··· 57 56 msecs_to_jiffies(heartbeat_data->period); 58 57 delay = msecs_to_jiffies(70); 59 58 heartbeat_data->phase++; 60 - brightness = led_cdev->max_brightness; 59 + if (!heartbeat_data->invert) 60 + brightness = led_cdev->max_brightness; 61 61 break; 62 62 case 1: 63 63 delay = heartbeat_data->period / 4 - msecs_to_jiffies(70); 64 64 heartbeat_data->phase++; 65 + if (heartbeat_data->invert) 66 + brightness = led_cdev->max_brightness; 65 67 break; 66 68 case 2: 67 69 delay = msecs_to_jiffies(70); 68 70 heartbeat_data->phase++; 69 - brightness = led_cdev->max_brightness; 71 + if (!heartbeat_data->invert) 72 + brightness = led_cdev->max_brightness; 70 73 break; 71 74 default: 72 75 delay = heartbeat_data->period - heartbeat_data->period / 4 - 73 76 msecs_to_jiffies(70); 74 77 heartbeat_data->phase = 0; 78 + if (heartbeat_data->invert) 79 + brightness = led_cdev->max_brightness; 75 80 break; 76 81 } 77 82 ··· 85 78 mod_timer(&heartbeat_data->timer, jiffies + delay); 86 79 } 87 80 81 + static ssize_t led_invert_show(struct device *dev, 82 + struct device_attribute *attr, char *buf) 83 + { 84 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 85 + struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data; 86 + 87 + return sprintf(buf, "%u\n", heartbeat_data->invert); 88 + } 89 + 90 + static ssize_t led_invert_store(struct device *dev, 91 + struct device_attribute *attr, const char *buf, size_t size) 92 + { 93 + struct led_classdev *led_cdev = dev_get_drvdata(dev); 94 + struct heartbeat_trig_data *heartbeat_data = led_cdev->trigger_data; 95 + unsigned long state; 96 + int ret; 97 + 98 + ret = kstrtoul(buf, 0, &state); 99 + if (ret) 100 + return ret; 101 + 102 + heartbeat_data->invert = !!state; 103 + 104 + return size; 105 + } 106 + 107 + static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store); 108 + 88 109 static void heartbeat_trig_activate(struct led_classdev *led_cdev) 89 110 { 90 111 struct heartbeat_trig_data *heartbeat_data; 112 + int rc; 91 113 92 114 heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL); 93 115 if (!heartbeat_data) 94 116 return; 95 117 96 118 led_cdev->trigger_data = heartbeat_data; 119 + rc = device_create_file(led_cdev->dev, &dev_attr_invert); 120 + if (rc) { 121 + kfree(led_cdev->trigger_data); 122 + return; 123 + } 124 + 97 125 setup_timer(&heartbeat_data->timer, 98 126 led_heartbeat_function, (unsigned long) led_cdev); 99 127 heartbeat_data->phase = 0; ··· 142 100 143 101 if (led_cdev->activated) { 144 102 del_timer_sync(&heartbeat_data->timer); 103 + device_remove_file(led_cdev->dev, &dev_attr_invert); 145 104 kfree(heartbeat_data); 146 105 led_cdev->activated = false; 147 106 }