Skip to content

Commit 42a9eaa

Browse files
Ansuellag-linaro
authored andcommitted
leds: leds-lp55xx: Generalize run_engine function
Generalize run_engine function for lp55xx based LED driver. The logic is similar to every LED driver, rework it with more macro magic and account for LED model that might have OP MODE and EXEC at base offset in the reg. Update any lp55xx based LED driver to use this generalized function and declare required bits. Suggested-by: Lee Jones <lee@kernel.org> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> Link: https://lore.kernel.org/r/20240626160027.19703-8-ansuelsmth@gmail.com Signed-off-by: Lee Jones <lee@kernel.org>
1 parent 409a9dc commit 42a9eaa

6 files changed

Lines changed: 65 additions & 146 deletions

File tree

drivers/leds/leds-lp5521.c

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,6 @@ static void lp5521_stop_engine(struct lp55xx_chip *chip)
132132
static void lp5521_run_engine(struct lp55xx_chip *chip, bool start)
133133
{
134134
int ret;
135-
u8 mode;
136-
u8 exec;
137135

138136
/* stop engine */
139137
if (!start) {
@@ -143,40 +141,9 @@ static void lp5521_run_engine(struct lp55xx_chip *chip, bool start)
143141
return;
144142
}
145143

146-
/*
147-
* To run the engine,
148-
* operation mode and enable register should updated at the same time
149-
*/
150-
151-
ret = lp55xx_read(chip, LP5521_REG_OP_MODE, &mode);
152-
if (ret)
153-
return;
154-
155-
ret = lp55xx_read(chip, LP5521_REG_ENABLE, &exec);
156-
if (ret)
157-
return;
158-
159-
/* change operation mode to RUN only when each engine is loading */
160-
if (LP5521_R_IS_LOADING(mode)) {
161-
mode = (mode & ~LP5521_MODE_R_M) | LP5521_RUN_R;
162-
exec = (exec & ~LP5521_EXEC_R_M) | LP5521_RUN_R;
163-
}
164-
165-
if (LP5521_G_IS_LOADING(mode)) {
166-
mode = (mode & ~LP5521_MODE_G_M) | LP5521_RUN_G;
167-
exec = (exec & ~LP5521_EXEC_G_M) | LP5521_RUN_G;
168-
}
169-
170-
if (LP5521_B_IS_LOADING(mode)) {
171-
mode = (mode & ~LP5521_MODE_B_M) | LP5521_RUN_B;
172-
exec = (exec & ~LP5521_EXEC_B_M) | LP5521_RUN_B;
173-
}
174-
175-
lp55xx_write(chip, LP5521_REG_OP_MODE, mode);
176-
lp5521_wait_opmode_done();
177-
178-
lp55xx_update_bits(chip, LP5521_REG_ENABLE, LP5521_EXEC_M, exec);
179-
lp5521_wait_enable_done();
144+
ret = lp55xx_run_engine_common(chip);
145+
if (!ret)
146+
lp5521_wait_enable_done();
180147
}
181148

182149
static int lp5521_update_program_memory(struct lp55xx_chip *chip,
@@ -476,6 +443,9 @@ static struct lp55xx_device_config lp5521_cfg = {
476443
.reg_op_mode = {
477444
.addr = LP5521_REG_OP_MODE,
478445
},
446+
.reg_exec = {
447+
.addr = LP5521_REG_ENABLE,
448+
},
479449
.reset = {
480450
.addr = LP5521_REG_RESET,
481451
.val = LP5521_RESET,

drivers/leds/leds-lp5523.c

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -184,50 +184,14 @@ static void lp5523_turn_off_channels(struct lp55xx_chip *chip)
184184

185185
static void lp5523_run_engine(struct lp55xx_chip *chip, bool start)
186186
{
187-
int ret;
188-
u8 mode;
189-
u8 exec;
190-
191187
/* stop engine */
192188
if (!start) {
193189
lp5523_stop_engine(chip);
194190
lp5523_turn_off_channels(chip);
195191
return;
196192
}
197193

198-
/*
199-
* To run the engine,
200-
* operation mode and enable register should updated at the same time
201-
*/
202-
203-
ret = lp55xx_read(chip, LP5523_REG_OP_MODE, &mode);
204-
if (ret)
205-
return;
206-
207-
ret = lp55xx_read(chip, LP5523_REG_ENABLE, &exec);
208-
if (ret)
209-
return;
210-
211-
/* change operation mode to RUN only when each engine is loading */
212-
if (LP5523_ENG1_IS_LOADING(mode)) {
213-
mode = (mode & ~LP5523_MODE_ENG1_M) | LP5523_RUN_ENG1;
214-
exec = (exec & ~LP5523_EXEC_ENG1_M) | LP5523_RUN_ENG1;
215-
}
216-
217-
if (LP5523_ENG2_IS_LOADING(mode)) {
218-
mode = (mode & ~LP5523_MODE_ENG2_M) | LP5523_RUN_ENG2;
219-
exec = (exec & ~LP5523_EXEC_ENG2_M) | LP5523_RUN_ENG2;
220-
}
221-
222-
if (LP5523_ENG3_IS_LOADING(mode)) {
223-
mode = (mode & ~LP5523_MODE_ENG3_M) | LP5523_RUN_ENG3;
224-
exec = (exec & ~LP5523_EXEC_ENG3_M) | LP5523_RUN_ENG3;
225-
}
226-
227-
lp55xx_write(chip, LP5523_REG_OP_MODE, mode);
228-
lp5523_wait_opmode_done();
229-
230-
lp55xx_update_bits(chip, LP5523_REG_ENABLE, LP5523_EXEC_M, exec);
194+
lp55xx_run_engine_common(chip);
231195
}
232196

233197
static int lp5523_init_program_engine(struct lp55xx_chip *chip)
@@ -840,6 +804,9 @@ static struct lp55xx_device_config lp5523_cfg = {
840804
.reg_op_mode = {
841805
.addr = LP5523_REG_OP_MODE,
842806
},
807+
.reg_exec = {
808+
.addr = LP5523_REG_ENABLE,
809+
},
843810
.engine_busy = {
844811
.addr = LP5523_REG_STATUS,
845812
.mask = LP5523_ENGINE_BUSY,

drivers/leds/leds-lp5562.c

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,6 @@ static void lp5562_set_led_current(struct lp55xx_led *led, u8 led_current)
127127
static void lp5562_run_engine(struct lp55xx_chip *chip, bool start)
128128
{
129129
int ret;
130-
u8 mode;
131-
u8 exec;
132130

133131
/* stop engine */
134132
if (!start) {
@@ -141,40 +139,9 @@ static void lp5562_run_engine(struct lp55xx_chip *chip, bool start)
141139
return;
142140
}
143141

144-
/*
145-
* To run the engine,
146-
* operation mode and enable register should updated at the same time
147-
*/
148-
149-
ret = lp55xx_read(chip, LP5562_REG_OP_MODE, &mode);
150-
if (ret)
151-
return;
152-
153-
ret = lp55xx_read(chip, LP5562_REG_ENABLE, &exec);
154-
if (ret)
155-
return;
156-
157-
/* change operation mode to RUN only when each engine is loading */
158-
if (LP5562_ENG1_IS_LOADING(mode)) {
159-
mode = (mode & ~LP5562_MODE_ENG1_M) | LP5562_RUN_ENG1;
160-
exec = (exec & ~LP5562_EXEC_ENG1_M) | LP5562_RUN_ENG1;
161-
}
162-
163-
if (LP5562_ENG2_IS_LOADING(mode)) {
164-
mode = (mode & ~LP5562_MODE_ENG2_M) | LP5562_RUN_ENG2;
165-
exec = (exec & ~LP5562_EXEC_ENG2_M) | LP5562_RUN_ENG2;
166-
}
167-
168-
if (LP5562_ENG3_IS_LOADING(mode)) {
169-
mode = (mode & ~LP5562_MODE_ENG3_M) | LP5562_RUN_ENG3;
170-
exec = (exec & ~LP5562_EXEC_ENG3_M) | LP5562_RUN_ENG3;
171-
}
172-
173-
lp55xx_write(chip, LP5562_REG_OP_MODE, mode);
174-
lp5562_wait_opmode_done();
175-
176-
lp55xx_update_bits(chip, LP5562_REG_ENABLE, LP5562_EXEC_M, exec);
177-
lp5562_wait_enable_done();
142+
ret = lp55xx_run_engine_common(chip);
143+
if (!ret)
144+
lp5562_wait_enable_done();
178145
}
179146

180147
static int lp5562_update_firmware(struct lp55xx_chip *chip,
@@ -472,6 +439,9 @@ static struct lp55xx_device_config lp5562_cfg = {
472439
.reg_op_mode = {
473440
.addr = LP5562_REG_OP_MODE,
474441
},
442+
.reg_exec = {
443+
.addr = LP5562_REG_ENABLE,
444+
},
475445
.reset = {
476446
.addr = LP5562_REG_RESET,
477447
.val = LP5562_RESET,

drivers/leds/leds-lp55xx-common.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@
4646
#define LP55xx_MODE_ENGn_GET(n, mode, shift) \
4747
(((mode) >> LP55xx_MODE_ENGn_SHIFT(n, shift)) & LP55xx_MODE_ENG_MASK)
4848

49+
#define LP55xx_EXEC_ENG_MASK GENMASK(1, 0)
50+
#define LP55xx_EXEC_HOLD_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x0)
51+
#define LP55xx_EXEC_STEP_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x1)
52+
#define LP55xx_EXEC_RUN_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x2)
53+
#define LP55xx_EXEC_ONCE_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x3)
54+
55+
#define LP55xx_EXEC_ENGn_SHIFT(n, shift) ((shift) + (2 * (3 - (n))))
56+
#define LP55xx_EXEC_ENGn_MASK(n, shift) (LP55xx_EXEC_ENG_MASK << LP55xx_EXEC_ENGn_SHIFT(n, shift))
57+
4958
/* Memory Page Selection */
5059
#define LP55xx_REG_PROG_PAGE_SEL 0x4f
5160
/* If supported, each ENGINE have an equal amount of pages offset from page 0 */
@@ -117,6 +126,40 @@ void lp55xx_load_engine(struct lp55xx_chip *chip)
117126
}
118127
EXPORT_SYMBOL_GPL(lp55xx_load_engine);
119128

129+
int lp55xx_run_engine_common(struct lp55xx_chip *chip)
130+
{
131+
const struct lp55xx_device_config *cfg = chip->cfg;
132+
u8 mode, exec;
133+
int i, ret;
134+
135+
/* To run the engine, both OP MODE and EXEC needs to be put in RUN mode */
136+
ret = lp55xx_read(chip, cfg->reg_op_mode.addr, &mode);
137+
if (ret)
138+
return ret;
139+
140+
ret = lp55xx_read(chip, cfg->reg_exec.addr, &exec);
141+
if (ret)
142+
return ret;
143+
144+
/* Switch to RUN only for engine that were put in LOAD previously */
145+
for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) {
146+
if (LP55xx_MODE_ENGn_GET(i, mode, cfg->reg_op_mode.shift) != LP55xx_MODE_LOAD_ENG)
147+
continue;
148+
149+
mode &= ~LP55xx_MODE_ENGn_MASK(i, cfg->reg_op_mode.shift);
150+
mode |= LP55xx_MODE_RUN_ENG << LP55xx_MODE_ENGn_SHIFT(i, cfg->reg_op_mode.shift);
151+
exec &= ~LP55xx_EXEC_ENGn_MASK(i, cfg->reg_exec.shift);
152+
exec |= LP55xx_EXEC_RUN_ENG << LP55xx_EXEC_ENGn_SHIFT(i, cfg->reg_exec.shift);
153+
}
154+
155+
lp55xx_write(chip, cfg->reg_op_mode.addr, mode);
156+
lp55xx_wait_opmode_done(chip);
157+
lp55xx_write(chip, cfg->reg_exec.addr, exec);
158+
159+
return 0;
160+
}
161+
EXPORT_SYMBOL_GPL(lp55xx_run_engine_common);
162+
120163
static void lp55xx_reset_device(struct lp55xx_chip *chip)
121164
{
122165
const struct lp55xx_device_config *cfg = chip->cfg;

drivers/leds/leds-lp55xx-common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ struct lp55xx_reg {
112112
*/
113113
struct lp55xx_device_config {
114114
const struct lp55xx_reg reg_op_mode; /* addr, shift */
115+
const struct lp55xx_reg reg_exec; /* addr, shift */
115116
const struct lp55xx_reg engine_busy; /* addr, mask */
116117
const struct lp55xx_reg reset;
117118
const struct lp55xx_reg enable;
@@ -206,6 +207,7 @@ extern bool lp55xx_is_extclk_used(struct lp55xx_chip *chip);
206207
/* common chip functions */
207208
extern void lp55xx_stop_all_engine(struct lp55xx_chip *chip);
208209
extern void lp55xx_load_engine(struct lp55xx_chip *chip);
210+
extern int lp55xx_run_engine_common(struct lp55xx_chip *chip);
209211

210212
/* common probe/remove function */
211213
extern int lp55xx_probe(struct i2c_client *client);

drivers/leds/leds-lp8501.c

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -127,50 +127,14 @@ static void lp8501_turn_off_channels(struct lp55xx_chip *chip)
127127

128128
static void lp8501_run_engine(struct lp55xx_chip *chip, bool start)
129129
{
130-
int ret;
131-
u8 mode;
132-
u8 exec;
133-
134130
/* stop engine */
135131
if (!start) {
136132
lp55xx_stop_all_engine(chip);
137133
lp8501_turn_off_channels(chip);
138134
return;
139135
}
140136

141-
/*
142-
* To run the engine,
143-
* operation mode and enable register should updated at the same time
144-
*/
145-
146-
ret = lp55xx_read(chip, LP8501_REG_OP_MODE, &mode);
147-
if (ret)
148-
return;
149-
150-
ret = lp55xx_read(chip, LP8501_REG_ENABLE, &exec);
151-
if (ret)
152-
return;
153-
154-
/* change operation mode to RUN only when each engine is loading */
155-
if (LP8501_ENG1_IS_LOADING(mode)) {
156-
mode = (mode & ~LP8501_MODE_ENG1_M) | LP8501_RUN_ENG1;
157-
exec = (exec & ~LP8501_EXEC_ENG1_M) | LP8501_RUN_ENG1;
158-
}
159-
160-
if (LP8501_ENG2_IS_LOADING(mode)) {
161-
mode = (mode & ~LP8501_MODE_ENG2_M) | LP8501_RUN_ENG2;
162-
exec = (exec & ~LP8501_EXEC_ENG2_M) | LP8501_RUN_ENG2;
163-
}
164-
165-
if (LP8501_ENG3_IS_LOADING(mode)) {
166-
mode = (mode & ~LP8501_MODE_ENG3_M) | LP8501_RUN_ENG3;
167-
exec = (exec & ~LP8501_EXEC_ENG3_M) | LP8501_RUN_ENG3;
168-
}
169-
170-
lp55xx_write(chip, LP8501_REG_OP_MODE, mode);
171-
lp8501_wait_opmode_done();
172-
173-
lp55xx_update_bits(chip, LP8501_REG_ENABLE, LP8501_EXEC_M, exec);
137+
lp55xx_run_engine_common(chip);
174138
}
175139

176140
static int lp8501_update_program_memory(struct lp55xx_chip *chip,
@@ -258,6 +222,9 @@ static struct lp55xx_device_config lp8501_cfg = {
258222
.reg_op_mode = {
259223
.addr = LP8501_REG_OP_MODE,
260224
},
225+
.reg_exec = {
226+
.addr = LP8501_REG_ENABLE,
227+
},
261228
.engine_busy = {
262229
.addr = LP8501_REG_STATUS,
263230
.mask = LP8501_ENGINE_BUSY,

0 commit comments

Comments
 (0)