summaryrefslogtreecommitdiff
path: root/drivers/leds
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/leds-lp5521.c56
-rw-r--r--drivers/leds/leds-lp5523.c50
-rw-r--r--drivers/leds/leds-lp5562.c58
-rw-r--r--drivers/leds/leds-lp55xx-common.c57
-rw-r--r--drivers/leds/leds-lp55xx-common.h4
-rw-r--r--drivers/leds/leds-lp8501.c52
6 files changed, 79 insertions, 198 deletions
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 0b9f99f4fff2..7ea3e5715f59 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -146,55 +146,6 @@ static void lp5521_run_engine(struct lp55xx_chip *chip, bool start)
lp5521_wait_enable_done();
}
-static int lp5521_update_program_memory(struct lp55xx_chip *chip,
- const u8 *data, size_t size)
-{
- enum lp55xx_engine_index idx = chip->engine_idx;
- u8 pattern[LP5521_PROGRAM_LENGTH] = {0};
- static const u8 addr[] = {
- [LP55XX_ENGINE_1] = LP5521_REG_R_PROG_MEM,
- [LP55XX_ENGINE_2] = LP5521_REG_G_PROG_MEM,
- [LP55XX_ENGINE_3] = LP5521_REG_B_PROG_MEM,
- };
- unsigned cmd;
- char c[3];
- int nrchars;
- int ret;
- int offset = 0;
- int 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);
- if (ret != 1)
- goto err;
-
- ret = sscanf(c, "%2x", &cmd);
- if (ret != 1)
- goto err;
-
- pattern[i] = (u8)cmd;
- offset += nrchars;
- i++;
- }
-
- /* Each instruction is 16bit long. Check that length is even */
- if (i % 2)
- goto err;
-
- for (i = 0; i < LP5521_PROGRAM_LENGTH; i++) {
- ret = lp55xx_write(chip, addr[idx] + i, pattern[i]);
- if (ret)
- return -EINVAL;
- }
-
- return size;
-
-err:
- dev_err(&chip->cl->dev, "wrong pattern format\n");
- return -EINVAL;
-}
-
static void lp5521_firmware_loaded(struct lp55xx_chip *chip)
{
const struct firmware *fw = chip->fw;
@@ -212,7 +163,7 @@ static void lp5521_firmware_loaded(struct lp55xx_chip *chip)
*/
lp55xx_load_engine(chip);
- lp5521_update_program_memory(chip, fw->data, fw->size);
+ lp55xx_update_program_memory(chip, fw->data, fw->size);
}
static int lp5521_post_init_device(struct lp55xx_chip *chip)
@@ -389,7 +340,7 @@ static ssize_t store_engine_load(struct device *dev,
chip->engine_idx = nr;
lp55xx_load_engine(chip);
- ret = lp5521_update_program_memory(chip, buf, len);
+ ret = lp55xx_update_program_memory(chip, buf, len);
mutex_unlock(&chip->lock);
@@ -454,6 +405,9 @@ static struct lp55xx_device_config lp5521_cfg = {
.addr = LP5521_REG_ENABLE,
.val = LP5521_ENABLE_DEFAULT,
},
+ .prog_mem_base = {
+ .addr = LP5521_REG_R_PROG_MEM,
+ },
.max_channel = LP5521_MAX_LEDS,
.post_init_device = lp5521_post_init_device,
.brightness_fn = lp5521_led_brightness,
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index b28955b72189..395c57330484 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -254,49 +254,6 @@ out:
return ret;
}
-static int lp5523_update_program_memory(struct lp55xx_chip *chip,
- const u8 *data, size_t size)
-{
- u8 pattern[LP5523_PROGRAM_LENGTH] = {0};
- unsigned int cmd;
- char c[3];
- int nrchars;
- int ret;
- int offset = 0;
- int i = 0;
-
- while ((offset < size - 1) && (i < LP5523_PROGRAM_LENGTH)) {
- /* separate sscanfs because length is working only for %s */
- ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
- if (ret != 1)
- goto err;
-
- ret = sscanf(c, "%2x", &cmd);
- if (ret != 1)
- goto err;
-
- pattern[i] = (u8)cmd;
- offset += nrchars;
- i++;
- }
-
- /* Each instruction is 16bit long. Check that length is even */
- if (i % 2)
- goto err;
-
- for (i = 0; i < LP5523_PROGRAM_LENGTH; i++) {
- ret = lp55xx_write(chip, LP5523_REG_PROG_MEM + i, pattern[i]);
- if (ret)
- return -EINVAL;
- }
-
- return size;
-
-err:
- dev_err(&chip->cl->dev, "wrong pattern format\n");
- return -EINVAL;
-}
-
static void lp5523_firmware_loaded(struct lp55xx_chip *chip)
{
const struct firmware *fw = chip->fw;
@@ -314,7 +271,7 @@ static void lp5523_firmware_loaded(struct lp55xx_chip *chip)
*/
lp55xx_load_engine(chip);
- lp5523_update_program_memory(chip, fw->data, fw->size);
+ lp55xx_update_program_memory(chip, fw->data, fw->size);
}
static ssize_t show_engine_mode(struct device *dev,
@@ -496,7 +453,7 @@ static ssize_t store_engine_load(struct device *dev,
chip->engine_idx = nr;
lp55xx_load_engine(chip);
- ret = lp5523_update_program_memory(chip, buf, len);
+ ret = lp55xx_update_program_memory(chip, buf, len);
mutex_unlock(&chip->lock);
@@ -819,6 +776,9 @@ static struct lp55xx_device_config lp5523_cfg = {
.addr = LP5523_REG_ENABLE,
.val = LP5523_ENABLE,
},
+ .prog_mem_base = {
+ .addr = LP5523_REG_PROG_MEM,
+ },
.pages_per_engine = LP5523_PAGES_PER_ENGINE,
.max_channel = LP5523_MAX_LEDS,
.post_init_device = lp5523_post_init_device,
diff --git a/drivers/leds/leds-lp5562.c b/drivers/leds/leds-lp5562.c
index fb05439576c3..7f3733fc446e 100644
--- a/drivers/leds/leds-lp5562.c
+++ b/drivers/leds/leds-lp5562.c
@@ -144,59 +144,6 @@ static void lp5562_run_engine(struct lp55xx_chip *chip, bool start)
lp5562_wait_enable_done();
}
-static int lp5562_update_firmware(struct lp55xx_chip *chip,
- const u8 *data, size_t size)
-{
- enum lp55xx_engine_index idx = chip->engine_idx;
- u8 pattern[LP5562_PROGRAM_LENGTH] = {0};
- static const u8 addr[] = {
- [LP55XX_ENGINE_1] = LP5562_REG_PROG_MEM_ENG1,
- [LP55XX_ENGINE_2] = LP5562_REG_PROG_MEM_ENG2,
- [LP55XX_ENGINE_3] = LP5562_REG_PROG_MEM_ENG3,
- };
- 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 < LP5562_PROGRAM_LENGTH; i++)
- lp55xx_write(chip, addr[idx] + i, 0);
-
- i = 0;
- while ((offset < size - 1) && (i < LP5562_PROGRAM_LENGTH)) {
- /* separate sscanfs because length is working only for %s */
- ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
- if (ret != 1)
- goto err;
-
- ret = sscanf(c, "%2x", &cmd);
- if (ret != 1)
- goto err;
-
- pattern[i] = (u8)cmd;
- offset += nrchars;
- i++;
- }
-
- /* Each instruction is 16bit long. Check that length is even */
- if (i % 2)
- goto err;
-
- program_size = i;
- for (i = 0; i < program_size; i++)
- lp55xx_write(chip, addr[idx] + i, pattern[i]);
-
- return 0;
-
-err:
- dev_err(&chip->cl->dev, "wrong pattern format\n");
- return -EINVAL;
-}
-
static void lp5562_firmware_loaded(struct lp55xx_chip *chip)
{
const struct firmware *fw = chip->fw;
@@ -218,7 +165,7 @@ static void lp5562_firmware_loaded(struct lp55xx_chip *chip)
*/
lp55xx_load_engine(chip);
- lp5562_update_firmware(chip, fw->data, fw->size);
+ lp55xx_update_program_memory(chip, fw->data, fw->size);
}
static int lp5562_post_init_device(struct lp55xx_chip *chip)
@@ -450,6 +397,9 @@ static struct lp55xx_device_config lp5562_cfg = {
.addr = LP5562_REG_ENABLE,
.val = LP5562_ENABLE_DEFAULT,
},
+ .prog_mem_base = {
+ .addr = LP5562_REG_PROG_MEM_ENG1,
+ },
.post_init_device = lp5562_post_init_device,
.set_led_current = lp5562_set_led_current,
.brightness_fn = lp5562_led_brightness,
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c
index 9830df285b96..8c20d7b4bc82 100644
--- a/drivers/leds/leds-lp55xx-common.c
+++ b/drivers/leds/leds-lp55xx-common.c
@@ -27,6 +27,8 @@
/* OP MODE require at least 153 us to clear regs */
#define LP55XX_CMD_SLEEP 200
+#define LP55xx_PROGRAM_LENGTH 32
+
/*
* Program Memory Operations
* Same Mask for each engine for both mode and exec
@@ -160,6 +162,61 @@ int lp55xx_run_engine_common(struct lp55xx_chip *chip)
}
EXPORT_SYMBOL_GPL(lp55xx_run_engine_common);
+int lp55xx_update_program_memory(struct lp55xx_chip *chip,
+ const u8 *data, size_t size)
+{
+ enum lp55xx_engine_index idx = chip->engine_idx;
+ const struct lp55xx_device_config *cfg = chip->cfg;
+ u8 pattern[LP55xx_PROGRAM_LENGTH] = { };
+ u8 start_addr = cfg->prog_mem_base.addr;
+ int i = 0, offset = 0;
+ int ret;
+
+ while ((offset < size - 1) && (i < LP55xx_PROGRAM_LENGTH)) {
+ unsigned int cmd;
+ int nrchars;
+ char c[3];
+
+ /* separate sscanfs because length is working only for %s */
+ ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
+ if (ret != 1)
+ goto err;
+
+ ret = sscanf(c, "%2x", &cmd);
+ if (ret != 1)
+ goto err;
+
+ pattern[i] = (u8)cmd;
+ offset += nrchars;
+ i++;
+ }
+
+ /* Each instruction is 16bit long. Check that length is even */
+ if (i % 2)
+ goto err;
+
+ /*
+ * For legacy LED chip with no page support, engine base address are
+ * one after another at offset of 32.
+ * For LED chip that support page, PAGE is already set in load_engine.
+ */
+ if (!cfg->pages_per_engine)
+ start_addr += LP55xx_PROGRAM_LENGTH * idx;
+
+ for (i = 0; i < LP55xx_PROGRAM_LENGTH; i++) {
+ ret = lp55xx_write(chip, start_addr + i, pattern[i]);
+ if (ret)
+ return -EINVAL;
+ }
+
+ return size;
+
+err:
+ dev_err(&chip->cl->dev, "wrong pattern format\n");
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(lp55xx_update_program_memory);
+
static void lp55xx_reset_device(struct lp55xx_chip *chip)
{
const struct lp55xx_device_config *cfg = chip->cfg;
diff --git a/drivers/leds/leds-lp55xx-common.h b/drivers/leds/leds-lp55xx-common.h
index dd74b214ec74..f0bbd41fdab3 100644
--- a/drivers/leds/leds-lp55xx-common.h
+++ b/drivers/leds/leds-lp55xx-common.h
@@ -99,6 +99,7 @@ struct lp55xx_reg {
* (if not supported 153 us sleep)
* @reset : Chip specific reset command
* @enable : Chip specific enable command
+ * @prog_mem_base : Chip specific base reg address for chip SMEM programming
* @pages_per_engine : Assigned pages for each engine
* (if not set chip doesn't support pages)
* @max_channel : Maximum number of channels
@@ -116,6 +117,7 @@ struct lp55xx_device_config {
const struct lp55xx_reg engine_busy; /* addr, mask */
const struct lp55xx_reg reset;
const struct lp55xx_reg enable;
+ const struct lp55xx_reg prog_mem_base;
const int pages_per_engine;
const int max_channel;
@@ -208,6 +210,8 @@ extern bool lp55xx_is_extclk_used(struct lp55xx_chip *chip);
extern void lp55xx_stop_all_engine(struct lp55xx_chip *chip);
extern void lp55xx_load_engine(struct lp55xx_chip *chip);
extern int lp55xx_run_engine_common(struct lp55xx_chip *chip);
+extern int lp55xx_update_program_memory(struct lp55xx_chip *chip,
+ const u8 *data, size_t size);
/* common probe/remove function */
extern int lp55xx_probe(struct i2c_client *client);
diff --git a/drivers/leds/leds-lp8501.c b/drivers/leds/leds-lp8501.c
index 47b30e9d04a2..d4094d20bdc1 100644
--- a/drivers/leds/leds-lp8501.c
+++ b/drivers/leds/leds-lp8501.c
@@ -137,53 +137,6 @@ static void lp8501_run_engine(struct lp55xx_chip *chip, bool start)
lp55xx_run_engine_common(chip);
}
-static int lp8501_update_program_memory(struct lp55xx_chip *chip,
- const u8 *data, size_t size)
-{
- u8 pattern[LP8501_PROGRAM_LENGTH] = {0};
- unsigned cmd;
- char c[3];
- int update_size;
- int nrchars;
- int offset = 0;
- int ret;
- int i;
-
- /* clear program memory before updating */
- for (i = 0; i < LP8501_PROGRAM_LENGTH; i++)
- lp55xx_write(chip, LP8501_REG_PROG_MEM + i, 0);
-
- i = 0;
- while ((offset < size - 1) && (i < LP8501_PROGRAM_LENGTH)) {
- /* separate sscanfs because length is working only for %s */
- ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
- if (ret != 1)
- goto err;
-
- ret = sscanf(c, "%2x", &cmd);
- if (ret != 1)
- goto err;
-
- pattern[i] = (u8)cmd;
- offset += nrchars;
- i++;
- }
-
- /* Each instruction is 16bit long. Check that length is even */
- if (i % 2)
- goto err;
-
- update_size = i;
- for (i = 0; i < update_size; i++)
- lp55xx_write(chip, LP8501_REG_PROG_MEM + i, pattern[i]);
-
- return 0;
-
-err:
- dev_err(&chip->cl->dev, "wrong pattern format\n");
- return -EINVAL;
-}
-
static void lp8501_firmware_loaded(struct lp55xx_chip *chip)
{
const struct firmware *fw = chip->fw;
@@ -201,7 +154,7 @@ static void lp8501_firmware_loaded(struct lp55xx_chip *chip)
*/
lp55xx_load_engine(chip);
- lp8501_update_program_memory(chip, fw->data, fw->size);
+ lp55xx_update_program_memory(chip, fw->data, fw->size);
}
static int lp8501_led_brightness(struct lp55xx_led *led)
@@ -237,6 +190,9 @@ static struct lp55xx_device_config lp8501_cfg = {
.addr = LP8501_REG_ENABLE,
.val = LP8501_ENABLE,
},
+ .prog_mem_base = {
+ .addr = LP8501_REG_PROG_MEM,
+ },
.pages_per_engine = LP8501_PAGES_PER_ENGINE,
.max_channel = LP8501_MAX_LEDS,
.post_init_device = lp8501_post_init_device,