aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorMilo Kim <milo.kim@ti.com>2013-11-21 01:13:34 -0500
committerBryan Wu <cooloney@gmail.com>2014-01-27 20:28:48 -0500
commit28c9266b38a00a07497daad0237f7fa154652ece (patch)
tree211c339c861923ea835a3644eef88aa5f5633e50 /drivers/leds
parent1f431afdb4572c4f1dc8a3c5159fe910c53fc814 (diff)
leds: lp5521/5523: Fix multiple engine usage bug
Whenever the engine is loaded by the user-application, the operation mode is reset first. But it has a problem in case of multiple engine used because previous engine settings are cleared. The driver should update not whole 8bits but each engine bit by masking. On the other hands, whole engines should be reset when the driver is unloaded and on initializing the LP5523 driver. So, new functions are used for this handling - lp5521/5523_stop_all_engines(). Cc: Pali Rohár <pali.rohar@gmail.com> Signed-off-by: Milo Kim <milo.kim@ti.com> Signed-off-by: Bryan Wu <cooloney@gmail.com>
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/leds-lp5521.c18
-rw-r--r--drivers/leds/leds-lp5523.c20
2 files changed, 33 insertions, 5 deletions
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 05188351711d..26f89ac15998 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -152,12 +152,26 @@ static void lp5521_load_engine(struct lp55xx_chip *chip)
152 lp5521_wait_opmode_done(); 152 lp5521_wait_opmode_done();
153} 153}
154 154
155static void lp5521_stop_engine(struct lp55xx_chip *chip) 155static void lp5521_stop_all_engines(struct lp55xx_chip *chip)
156{ 156{
157 lp55xx_write(chip, LP5521_REG_OP_MODE, 0); 157 lp55xx_write(chip, LP5521_REG_OP_MODE, 0);
158 lp5521_wait_opmode_done(); 158 lp5521_wait_opmode_done();
159} 159}
160 160
161static void lp5521_stop_engine(struct lp55xx_chip *chip)
162{
163 enum lp55xx_engine_index idx = chip->engine_idx;
164 u8 mask[] = {
165 [LP55XX_ENGINE_1] = LP5521_MODE_R_M,
166 [LP55XX_ENGINE_2] = LP5521_MODE_G_M,
167 [LP55XX_ENGINE_3] = LP5521_MODE_B_M,
168 };
169
170 lp55xx_update_bits(chip, LP5521_REG_OP_MODE, mask[idx], 0);
171
172 lp5521_wait_opmode_done();
173}
174
161static void lp5521_run_engine(struct lp55xx_chip *chip, bool start) 175static void lp5521_run_engine(struct lp55xx_chip *chip, bool start)
162{ 176{
163 int ret; 177 int ret;
@@ -568,7 +582,7 @@ static int lp5521_remove(struct i2c_client *client)
568 struct lp55xx_led *led = i2c_get_clientdata(client); 582 struct lp55xx_led *led = i2c_get_clientdata(client);
569 struct lp55xx_chip *chip = led->chip; 583 struct lp55xx_chip *chip = led->chip;
570 584
571 lp5521_stop_engine(chip); 585 lp5521_stop_all_engines(chip);
572 lp55xx_unregister_sysfs(chip); 586 lp55xx_unregister_sysfs(chip);
573 lp55xx_unregister_leds(led, chip); 587 lp55xx_unregister_leds(led, chip);
574 lp55xx_deinit_device(chip); 588 lp55xx_deinit_device(chip);
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 6b553d9f4266..2ce172396242 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -187,12 +187,26 @@ static void lp5523_load_engine_and_select_page(struct lp55xx_chip *chip)
187 lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, page_sel[idx]); 187 lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, page_sel[idx]);
188} 188}
189 189
190static void lp5523_stop_engine(struct lp55xx_chip *chip) 190static void lp5523_stop_all_engines(struct lp55xx_chip *chip)
191{ 191{
192 lp55xx_write(chip, LP5523_REG_OP_MODE, 0); 192 lp55xx_write(chip, LP5523_REG_OP_MODE, 0);
193 lp5523_wait_opmode_done(); 193 lp5523_wait_opmode_done();
194} 194}
195 195
196static void lp5523_stop_engine(struct lp55xx_chip *chip)
197{
198 enum lp55xx_engine_index idx = chip->engine_idx;
199 u8 mask[] = {
200 [LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M,
201 [LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M,
202 [LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M,
203 };
204
205 lp55xx_update_bits(chip, LP5523_REG_OP_MODE, mask[idx], 0);
206
207 lp5523_wait_opmode_done();
208}
209
196static void lp5523_turn_off_channels(struct lp55xx_chip *chip) 210static void lp5523_turn_off_channels(struct lp55xx_chip *chip)
197{ 211{
198 int i; 212 int i;
@@ -303,7 +317,7 @@ static int lp5523_init_program_engine(struct lp55xx_chip *chip)
303 } 317 }
304 318
305out: 319out:
306 lp5523_stop_engine(chip); 320 lp5523_stop_all_engines(chip);
307 return ret; 321 return ret;
308} 322}
309 323
@@ -778,7 +792,7 @@ static int lp5523_remove(struct i2c_client *client)
778 struct lp55xx_led *led = i2c_get_clientdata(client); 792 struct lp55xx_led *led = i2c_get_clientdata(client);
779 struct lp55xx_chip *chip = led->chip; 793 struct lp55xx_chip *chip = led->chip;
780 794
781 lp5523_stop_engine(chip); 795 lp5523_stop_all_engines(chip);
782 lp55xx_unregister_sysfs(chip); 796 lp55xx_unregister_sysfs(chip);
783 lp55xx_unregister_leds(led, chip); 797 lp55xx_unregister_leds(led, chip);
784 lp55xx_deinit_device(chip); 798 lp55xx_deinit_device(chip);