[PATCH] [LEDS] Extend support of blinkm device Signed-off-by: Jan-Simon Möller <jansimon.moeller@xxxxxx> --- drivers/leds/leds-blinkm.c | 190 +++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 188 insertions(+), 2 deletions(-) diff --git a/drivers/leds/leds-blinkm.c b/drivers/leds/leds-blinkm.c index a502678..11e2201 100644 --- a/drivers/leds/leds-blinkm.c +++ b/drivers/leds/leds-blinkm.c @@ -77,7 +77,7 @@ struct blinkm_data { u8 next_brightness; /* HSB brightness */ /* currently unused / todo */ u8 fade_speed; /* fade speed 1 - 255 */ - s8 time_adjust; /* time adjust -128 - 127 */ + s8 time_adj; /* time adjust -128 - 127 */ u8 fade:1; /* fade on = 1, off = 0 */ u8 rand:1; /* rand fade mode on = 1 */ u8 script_id; /* script ID */ @@ -89,6 +89,9 @@ struct blinkm_data { #define RED 0 #define GREEN 1 #define BLUE 2 +#define HUE 3 +#define SAT 4 +#define BRI 5 /* mapping command names to cmd chars - see datasheet */ #define BLM_GO_RGB 0 @@ -299,13 +302,188 @@ static ssize_t store_test(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(test, S_IRUGO | S_IWUSR, show_test, store_test); -/* TODO: HSB, fade, timeadj, script ... */ + +static ssize_t show_runscript(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, + "#Write #id into runscript to start script #id (0-18) !#\n"); +} + +static ssize_t store_runscript(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client; + struct blinkm_data *data; + int ret; + u8 value; + + client = to_i2c_client(dev); + data = i2c_get_clientdata(client); + + ret = kstrtou8(buf, 10, &value); + if (ret < 0) { + dev_err(dev, "BlinkM: value too large!\n"); + return ret; + } + + if ( (value > 18) || (value < 0) ){ + dev_err(dev, "BlinkM: value too large!\n"); + return ret; + } + + data->script_id = value; + + ret = blinkm_transfer_hw(client, BLM_PLAY_SCRIPT); + if (ret < 0) { + dev_err(dev, "BlinkM: can't set RGB\n"); + return ret; + } + + return count; +} + +static DEVICE_ATTR(runscript, S_IRUGO | S_IWUSR, show_runscript, store_runscript); + + +static ssize_t show_stopscript(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, + "#Write into stopscript to stop (any) script !#\n"); +} + +static ssize_t store_stopscript(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + + struct i2c_client *client; + struct blinkm_data *data; + int ret; + + client = to_i2c_client(dev); + data = i2c_get_clientdata(client); + + ret = blinkm_transfer_hw(client, BLM_STOP_SCRIPT); + if (ret < 0) { + dev_err(dev, "BlinkM: can't set RGB\n"); + return ret; + } + + data->next_red = 0x00; + data->next_green = 0x00; + data->next_blue = 0x00; + ret = blinkm_transfer_hw(client, BLM_GO_RGB); + if (ret < 0) { + dev_err(dev, "BlinkM: can't set RGB\n"); + return ret; + } + + data->time_adj = 0; + ret = blinkm_transfer_hw(client, BLM_SET_TIME_ADJ); + if (ret < 0) { + dev_err(dev, "BlinkM: can't set RGB\n"); + return ret; + } + + + return count; +} + +static DEVICE_ATTR(stopscript, S_IRUGO | S_IWUSR, show_stopscript, store_stopscript); + +static ssize_t show_timeadj(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, + "#Write into timeadj to change time base. (-127 - 128) !#\n"); +} + +static ssize_t store_timeadj(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + + struct i2c_client *client; + struct blinkm_data *data; + int ret; + s8 value; + + client = to_i2c_client(dev); + data = i2c_get_clientdata(client); + + ret = kstrtos8(buf, 10, &value); + if (ret < 0) { + dev_err(dev, "BlinkM: value invalid!\n"); + return ret; + } + + data->time_adj=value; + + ret = blinkm_transfer_hw(client, BLM_SET_TIME_ADJ); + if (ret < 0) { + dev_err(dev, "BlinkM: can't set RGB\n"); + return ret; + } + + return count; +} + +static DEVICE_ATTR(timeadj, S_IRUGO | S_IWUSR, show_timeadj, store_timeadj); + +static ssize_t show_fadespeed(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return scnprintf(buf, PAGE_SIZE, + "#Write into fadespeed to change time of fading. (1 - 255) !#\n"); +} + +static ssize_t store_fadespeed(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + + struct i2c_client *client; + struct blinkm_data *data; + int ret; + u8 value; + + client = to_i2c_client(dev); + data = i2c_get_clientdata(client); + + ret = kstrtou8(buf, 10, &value); + if (ret < 0) { + dev_err(dev, "BlinkM: value invalid!\n"); + return ret; + } + + if (value == 0) { + dev_err(dev, "BlinkM: 0 not allowed!\n"); + return -1; + } + + data->fade_speed = value; + + ret = blinkm_transfer_hw(client, BLM_SET_FADE_SPEED); + if (ret < 0) { + dev_err(dev, "BlinkM: can't set RGB\n"); + return ret; + } + + return count; +} + +static DEVICE_ATTR(fadespeed, S_IRUGO | S_IWUSR, show_fadespeed, store_fadespeed); + +/* TODO: HSB, fade, timeadj, ... */ static struct attribute *blinkm_attrs[] = { &dev_attr_red.attr, &dev_attr_green.attr, &dev_attr_blue.attr, &dev_attr_test.attr, + &dev_attr_runscript.attr, + &dev_attr_stopscript.attr, + &dev_attr_timeadj.attr, + &dev_attr_fadespeed.attr, NULL, }; @@ -422,7 +600,13 @@ static int blinkm_transfer_hw(struct i2c_client *client, int cmd) data->i2c_addr = data->args[0]; break; case BLM_SET_TIME_ADJ: + data->args[0] = data->time_adj; + blinkm_write(client, cmd, data->args); + break; case BLM_SET_FADE_SPEED: + data->args[0] = data->fade_speed; + blinkm_write(client, cmd, data->args); + break; case BLM_READ_SCRIPT_LINE: case BLM_WRITE_SCRIPT_LINE: case BLM_SET_SCRIPT_LR: @@ -654,6 +838,8 @@ static int blinkm_probe(struct i2c_client *client, /* firmware version - use fake until we read real value * (currently broken - BlinkM confused!) */ data->script_id = 0x01; + data->script_repeats = 0x00; + data->script_startline = 0x00; data->i2c_client = client; i2c_set_clientdata(client, data); -- 1.7.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-leds" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html