drivers: s2mu004-rgb: fade led

Adapted to 4.4.y

Credits to Ktoonsez for the original implementation

Signed-off-by: BlackMesa123 <brother12@hotmail.it>
This commit is contained in:
Noxxxious 2018-08-13 01:37:31 +02:00 committed by BlackMesa123
parent 89af40d1bb
commit ffb8ecdc83

View File

@ -25,6 +25,10 @@
#include <linux/mfd/samsung/s2mu004-private.h>
#include <linux/leds-s2mu004-rgb.h>
unsigned int led_enable_fade = 1;
unsigned int led_fade_time_up = 800;
unsigned int led_fade_time_down = 800;
struct s2mu004_rgb_drvdata {
struct s2mu004_rgb_pdata *pdata;
struct i2c_client *i2c;
@ -75,12 +79,12 @@ static int s2mu004_rgb_ramp(struct s2mu004_rgb_drvdata *ddata,
int value;
int col = ddata->pdata->col[led];
if (ramp_up > 800)
ramp_up = ((ramp_up - 800) >> 1) + 800;
if (ramp_up > led_fade_time_up)
ramp_up = ((ramp_up - led_fade_time_up) >> 1) + led_fade_time_up;
ramp_up /= 100;
if (ramp_down > 800)
ramp_down = ((ramp_down - 800) >> 1) + 800;
if (ramp_down > led_fade_time_down)
ramp_down = ((ramp_down - led_fade_time_down) >> 1) + led_fade_time_down;
ramp_down /= 100;
value = (ramp_down) | (ramp_up << 4);
@ -148,12 +152,22 @@ static ssize_t store_s2mu004_rgb_pattern(struct device *dev,
ddata->ratio[LED_RED], LED_BLINK);
break;
case MISSED_NOTI:
s2mu004_rgb_blink(ddata, LED_BLUE, 500, 5000);
if (led_enable_fade) {
s2mu004_rgb_ramp(ddata, LED_BLUE, led_fade_time_up, led_fade_time_down);
s2mu004_rgb_blink(ddata, LED_BLUE, led_fade_time_up, 5000);
} else {
s2mu004_rgb_blink(ddata, LED_BLUE, 500, 5000);
}
s2mu004_rgb_set_state(ddata, LED_BLUE,
ddata->ratio[LED_BLUE], LED_BLINK);
break;
case LOW_BATTERY:
s2mu004_rgb_blink(ddata, LED_RED, 500, 5000);
if (led_enable_fade) {
s2mu004_rgb_ramp(ddata, LED_RED, led_fade_time_up, led_fade_time_down);
s2mu004_rgb_blink(ddata, LED_RED, led_fade_time_up, 5000);
} else {
s2mu004_rgb_blink(ddata, LED_RED, 500, 5000);
}
s2mu004_rgb_set_state(ddata, LED_RED,
ddata->ratio[LED_RED], LED_BLINK);
break;
@ -162,8 +176,13 @@ static ssize_t store_s2mu004_rgb_pattern(struct device *dev,
ddata->ratio[LED_GREEN], LED_ALWAYS_ON);
break;
case POWERING:
s2mu004_rgb_ramp(ddata, LED_GREEN, 800, 800);
s2mu004_rgb_blink(ddata, LED_GREEN, 200, 200);
if (led_enable_fade) {
s2mu004_rgb_ramp(ddata, LED_GREEN, led_fade_time_up, led_fade_time_down);
s2mu004_rgb_blink(ddata, LED_GREEN, led_fade_time_up, 5000);
} else {
s2mu004_rgb_ramp(ddata, LED_GREEN, 800, 800);
s2mu004_rgb_blink(ddata, LED_GREEN, 200, 200);
}
s2mu004_rgb_set_state(ddata, LED_BLUE,
ddata->ratio[LED_BLUE], LED_ALWAYS_ON);
s2mu004_rgb_set_state(ddata, LED_GREEN,
@ -203,6 +222,9 @@ static ssize_t store_s2mu004_rgb_blink(struct device *dev,
for (i = 0; i < ddata->pdata->nleds; i++) {
if (br[i]) {
if (led_enable_fade && on > 0)
s2mu004_rgb_ramp(ddata, i, led_fade_time_up, led_fade_time_down);
if (!off)
s2mu004_rgb_set_state(ddata, i, br[i], LED_ALWAYS_ON);
else {
@ -257,6 +279,64 @@ static ssize_t store_s2mu004_rgb_lowpower(struct device *dev,
return count;
}
static ssize_t led_fade_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int ret;
ret = snprintf(buf, 30, "%d\n", led_enable_fade);
pr_info("[LED] %s: led_fade=%d\n", __func__, led_enable_fade);
return ret;
}
static ssize_t led_fade_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int retval;
int enabled = 0;
retval = sscanf(buf, "%1d", &enabled);
if (retval != 0 && (enabled == 0 || enabled == 1))
led_enable_fade = enabled;
return count;
}
static ssize_t led_fade_time_up_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int ret;
ret = snprintf(buf, 30, "%d\n", led_fade_time_up);
pr_info("[LED] %s: led_fade=%d\n", __func__, led_fade_time_up);
return ret;
}
static ssize_t led_fade_time_up_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int retval;
int val = 0;
retval = sscanf(buf, "%1d", &val);
if (retval != 0 && val >= 100 && val <= 4000)
led_fade_time_up = val;
return count;
}
static ssize_t led_fade_time_down_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int ret;
ret = snprintf(buf, 30, "%d\n", led_fade_time_down);
pr_info("[LED] %s: led_fade=%d\n", __func__, led_fade_time_down);
return ret;
}
static ssize_t led_fade_time_down_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int retval;
int val = 0;
retval = sscanf(buf, "%1d", &val);
if (retval != 0 && val >= 100 && val <= 4000)
led_fade_time_down = val;
return count;
}
#define ATTR_STORE_RGB(name, type) \
static ssize_t store_led_##name(struct device *dev, \
struct device_attribute *devattr, const char *buf, size_t count)\
@ -281,6 +361,9 @@ static DEVICE_ATTR(led_pattern, 0660, NULL, store_s2mu004_rgb_pattern);
static DEVICE_ATTR(led_blink, 0660, NULL, store_s2mu004_rgb_blink);
static DEVICE_ATTR(led_brightness, 0660, NULL, store_s2mu004_rgb_brightness);
static DEVICE_ATTR(led_lowpower, 0660, NULL, store_s2mu004_rgb_lowpower);
static DEVICE_ATTR(led_fade, 0664, led_fade_show, led_fade_store);
static DEVICE_ATTR(led_fade_time_up, 0664, led_fade_time_up_show, led_fade_time_up_store);
static DEVICE_ATTR(led_fade_time_down, 0664, led_fade_time_down_show, led_fade_time_down_store);
static struct attribute *sec_led_attributes[] = {
&dev_attr_led_r.attr,
@ -290,6 +373,9 @@ static struct attribute *sec_led_attributes[] = {
&dev_attr_led_blink.attr,
&dev_attr_led_brightness.attr,
&dev_attr_led_lowpower.attr,
&dev_attr_led_fade.attr,
&dev_attr_led_fade_time_up.attr,
&dev_attr_led_fade_time_down.attr,
NULL,
};