diff options
Diffstat (limited to 'drivers/leds/leds-lp5521.c')
-rw-r--r-- | drivers/leds/leds-lp5521.c | 118 |
1 files changed, 103 insertions, 15 deletions
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index 1392feb1bcf7..05188351711d 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c @@ -220,17 +220,11 @@ static int lp5521_update_program_memory(struct lp55xx_chip *chip, }; unsigned cmd; char c[3]; - int program_size; int nrchars; - int offset = 0; int ret; - int i; - - /* clear program memory before updating */ - for (i = 0; i < LP5521_PROGRAM_LENGTH; i++) - lp55xx_write(chip, addr[idx] + i, 0); + int offset = 0; + int i = 0; - i = 0; while ((offset < size - 1) && (i < LP5521_PROGRAM_LENGTH)) { /* separate sscanfs because length is working only for %s */ ret = sscanf(data + offset, "%2s%n ", c, &nrchars); @@ -250,11 +244,19 @@ static int lp5521_update_program_memory(struct lp55xx_chip *chip, if (i % 2) goto err; - program_size = i; - for (i = 0; i < program_size; i++) - lp55xx_write(chip, addr[idx] + i, pattern[i]); + mutex_lock(&chip->lock); - return 0; + for (i = 0; i < LP5521_PROGRAM_LENGTH; i++) { + ret = lp55xx_write(chip, addr[idx] + i, pattern[i]); + if (ret) { + mutex_unlock(&chip->lock); + return -EINVAL; + } + } + + mutex_unlock(&chip->lock); + + return size; err: dev_err(&chip->cl->dev, "wrong pattern format\n"); @@ -365,6 +367,80 @@ static void lp5521_led_brightness_work(struct work_struct *work) mutex_unlock(&chip->lock); } +static ssize_t show_engine_mode(struct device *dev, + struct device_attribute *attr, + char *buf, int nr) +{ + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); + struct lp55xx_chip *chip = led->chip; + enum lp55xx_engine_mode mode = chip->engines[nr - 1].mode; + + switch (mode) { + case LP55XX_ENGINE_RUN: + return sprintf(buf, "run\n"); + case LP55XX_ENGINE_LOAD: + return sprintf(buf, "load\n"); + case LP55XX_ENGINE_DISABLED: + default: + return sprintf(buf, "disabled\n"); + } +} +show_mode(1) +show_mode(2) +show_mode(3) + +static ssize_t store_engine_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len, int nr) +{ + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); + struct lp55xx_chip *chip = led->chip; + struct lp55xx_engine *engine = &chip->engines[nr - 1]; + + mutex_lock(&chip->lock); + + chip->engine_idx = nr; + + if (!strncmp(buf, "run", 3)) { + lp5521_run_engine(chip, true); + engine->mode = LP55XX_ENGINE_RUN; + } else if (!strncmp(buf, "load", 4)) { + lp5521_stop_engine(chip); + lp5521_load_engine(chip); + engine->mode = LP55XX_ENGINE_LOAD; + } else if (!strncmp(buf, "disabled", 8)) { + lp5521_stop_engine(chip); + engine->mode = LP55XX_ENGINE_DISABLED; + } + + mutex_unlock(&chip->lock); + + return len; +} +store_mode(1) +store_mode(2) +store_mode(3) + +static ssize_t store_engine_load(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len, int nr) +{ + struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); + struct lp55xx_chip *chip = led->chip; + + mutex_lock(&chip->lock); + + chip->engine_idx = nr; + lp5521_load_engine(chip); + + mutex_unlock(&chip->lock); + + return lp5521_update_program_memory(chip, buf, len); +} +store_load(1) +store_load(2) +store_load(3) + static ssize_t lp5521_selftest(struct device *dev, struct device_attribute *attr, char *buf) @@ -381,9 +457,21 @@ static ssize_t lp5521_selftest(struct device *dev, } /* device attributes */ -static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL); +static LP55XX_DEV_ATTR_RW(engine1_mode, show_engine1_mode, store_engine1_mode); +static LP55XX_DEV_ATTR_RW(engine2_mode, show_engine2_mode, store_engine2_mode); +static LP55XX_DEV_ATTR_RW(engine3_mode, show_engine3_mode, store_engine3_mode); +static LP55XX_DEV_ATTR_WO(engine1_load, store_engine1_load); +static LP55XX_DEV_ATTR_WO(engine2_load, store_engine2_load); +static LP55XX_DEV_ATTR_WO(engine3_load, store_engine3_load); +static LP55XX_DEV_ATTR_RO(selftest, lp5521_selftest); static struct attribute *lp5521_attributes[] = { + &dev_attr_engine1_mode.attr, + &dev_attr_engine2_mode.attr, + &dev_attr_engine3_mode.attr, + &dev_attr_engine1_load.attr, + &dev_attr_engine2_load.attr, + &dev_attr_engine3_load.attr, &dev_attr_selftest.attr, NULL }; @@ -420,7 +508,7 @@ static int lp5521_probe(struct i2c_client *client, struct lp55xx_platform_data *pdata; struct device_node *np = client->dev.of_node; - if (!client->dev.platform_data) { + if (!dev_get_platdata(&client->dev)) { if (np) { ret = lp55xx_of_populate_pdata(&client->dev, np); if (ret < 0) @@ -430,7 +518,7 @@ static int lp5521_probe(struct i2c_client *client, return -EINVAL; } } - pdata = client->dev.platform_data; + pdata = dev_get_platdata(&client->dev); chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); if (!chip) |