static void lp5521_run_engine(struct lp55xx_chip *chip, bool start)
{
int ret;
- u8 mode;
- u8 exec;
/* stop engine */
if (!start) {
return;
}
- /*
- * To run the engine,
- * operation mode and enable register should updated at the same time
- */
-
- ret = lp55xx_read(chip, LP5521_REG_OP_MODE, &mode);
- if (ret)
- return;
-
- ret = lp55xx_read(chip, LP5521_REG_ENABLE, &exec);
- if (ret)
- return;
-
- /* change operation mode to RUN only when each engine is loading */
- if (LP5521_R_IS_LOADING(mode)) {
- mode = (mode & ~LP5521_MODE_R_M) | LP5521_RUN_R;
- exec = (exec & ~LP5521_EXEC_R_M) | LP5521_RUN_R;
- }
-
- if (LP5521_G_IS_LOADING(mode)) {
- mode = (mode & ~LP5521_MODE_G_M) | LP5521_RUN_G;
- exec = (exec & ~LP5521_EXEC_G_M) | LP5521_RUN_G;
- }
-
- if (LP5521_B_IS_LOADING(mode)) {
- mode = (mode & ~LP5521_MODE_B_M) | LP5521_RUN_B;
- exec = (exec & ~LP5521_EXEC_B_M) | LP5521_RUN_B;
- }
-
- lp55xx_write(chip, LP5521_REG_OP_MODE, mode);
- lp5521_wait_opmode_done();
-
- lp55xx_update_bits(chip, LP5521_REG_ENABLE, LP5521_EXEC_M, exec);
- lp5521_wait_enable_done();
+ ret = lp55xx_run_engine_common(chip);
+ if (!ret)
+ lp5521_wait_enable_done();
}
static int lp5521_update_program_memory(struct lp55xx_chip *chip,
.reg_op_mode = {
.addr = LP5521_REG_OP_MODE,
},
+ .reg_exec = {
+ .addr = LP5521_REG_ENABLE,
+ },
.reset = {
.addr = LP5521_REG_RESET,
.val = LP5521_RESET,
static void lp5523_run_engine(struct lp55xx_chip *chip, bool start)
{
- int ret;
- u8 mode;
- u8 exec;
-
/* stop engine */
if (!start) {
lp5523_stop_engine(chip);
return;
}
- /*
- * To run the engine,
- * operation mode and enable register should updated at the same time
- */
-
- ret = lp55xx_read(chip, LP5523_REG_OP_MODE, &mode);
- if (ret)
- return;
-
- ret = lp55xx_read(chip, LP5523_REG_ENABLE, &exec);
- if (ret)
- return;
-
- /* change operation mode to RUN only when each engine is loading */
- if (LP5523_ENG1_IS_LOADING(mode)) {
- mode = (mode & ~LP5523_MODE_ENG1_M) | LP5523_RUN_ENG1;
- exec = (exec & ~LP5523_EXEC_ENG1_M) | LP5523_RUN_ENG1;
- }
-
- if (LP5523_ENG2_IS_LOADING(mode)) {
- mode = (mode & ~LP5523_MODE_ENG2_M) | LP5523_RUN_ENG2;
- exec = (exec & ~LP5523_EXEC_ENG2_M) | LP5523_RUN_ENG2;
- }
-
- if (LP5523_ENG3_IS_LOADING(mode)) {
- mode = (mode & ~LP5523_MODE_ENG3_M) | LP5523_RUN_ENG3;
- exec = (exec & ~LP5523_EXEC_ENG3_M) | LP5523_RUN_ENG3;
- }
-
- lp55xx_write(chip, LP5523_REG_OP_MODE, mode);
- lp5523_wait_opmode_done();
-
- lp55xx_update_bits(chip, LP5523_REG_ENABLE, LP5523_EXEC_M, exec);
+ lp55xx_run_engine_common(chip);
}
static int lp5523_init_program_engine(struct lp55xx_chip *chip)
.reg_op_mode = {
.addr = LP5523_REG_OP_MODE,
},
+ .reg_exec = {
+ .addr = LP5523_REG_ENABLE,
+ },
.engine_busy = {
.addr = LP5523_REG_STATUS,
.mask = LP5523_ENGINE_BUSY,
static void lp5562_run_engine(struct lp55xx_chip *chip, bool start)
{
int ret;
- u8 mode;
- u8 exec;
/* stop engine */
if (!start) {
return;
}
- /*
- * To run the engine,
- * operation mode and enable register should updated at the same time
- */
-
- ret = lp55xx_read(chip, LP5562_REG_OP_MODE, &mode);
- if (ret)
- return;
-
- ret = lp55xx_read(chip, LP5562_REG_ENABLE, &exec);
- if (ret)
- return;
-
- /* change operation mode to RUN only when each engine is loading */
- if (LP5562_ENG1_IS_LOADING(mode)) {
- mode = (mode & ~LP5562_MODE_ENG1_M) | LP5562_RUN_ENG1;
- exec = (exec & ~LP5562_EXEC_ENG1_M) | LP5562_RUN_ENG1;
- }
-
- if (LP5562_ENG2_IS_LOADING(mode)) {
- mode = (mode & ~LP5562_MODE_ENG2_M) | LP5562_RUN_ENG2;
- exec = (exec & ~LP5562_EXEC_ENG2_M) | LP5562_RUN_ENG2;
- }
-
- if (LP5562_ENG3_IS_LOADING(mode)) {
- mode = (mode & ~LP5562_MODE_ENG3_M) | LP5562_RUN_ENG3;
- exec = (exec & ~LP5562_EXEC_ENG3_M) | LP5562_RUN_ENG3;
- }
-
- lp55xx_write(chip, LP5562_REG_OP_MODE, mode);
- lp5562_wait_opmode_done();
-
- lp55xx_update_bits(chip, LP5562_REG_ENABLE, LP5562_EXEC_M, exec);
- lp5562_wait_enable_done();
+ ret = lp55xx_run_engine_common(chip);
+ if (!ret)
+ lp5562_wait_enable_done();
}
static int lp5562_update_firmware(struct lp55xx_chip *chip,
.reg_op_mode = {
.addr = LP5562_REG_OP_MODE,
},
+ .reg_exec = {
+ .addr = LP5562_REG_ENABLE,
+ },
.reset = {
.addr = LP5562_REG_RESET,
.val = LP5562_RESET,
#define LP55xx_MODE_ENGn_GET(n, mode, shift) \
(((mode) >> LP55xx_MODE_ENGn_SHIFT(n, shift)) & LP55xx_MODE_ENG_MASK)
+#define LP55xx_EXEC_ENG_MASK GENMASK(1, 0)
+#define LP55xx_EXEC_HOLD_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x0)
+#define LP55xx_EXEC_STEP_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x1)
+#define LP55xx_EXEC_RUN_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x2)
+#define LP55xx_EXEC_ONCE_ENG FIELD_PREP_CONST(LP55xx_EXEC_ENG_MASK, 0x3)
+
+#define LP55xx_EXEC_ENGn_SHIFT(n, shift) ((shift) + (2 * (3 - (n))))
+#define LP55xx_EXEC_ENGn_MASK(n, shift) (LP55xx_EXEC_ENG_MASK << LP55xx_EXEC_ENGn_SHIFT(n, shift))
+
/* Memory Page Selection */
#define LP55xx_REG_PROG_PAGE_SEL 0x4f
/* If supported, each ENGINE have an equal amount of pages offset from page 0 */
}
EXPORT_SYMBOL_GPL(lp55xx_load_engine);
+int lp55xx_run_engine_common(struct lp55xx_chip *chip)
+{
+ const struct lp55xx_device_config *cfg = chip->cfg;
+ u8 mode, exec;
+ int i, ret;
+
+ /* To run the engine, both OP MODE and EXEC needs to be put in RUN mode */
+ ret = lp55xx_read(chip, cfg->reg_op_mode.addr, &mode);
+ if (ret)
+ return ret;
+
+ ret = lp55xx_read(chip, cfg->reg_exec.addr, &exec);
+ if (ret)
+ return ret;
+
+ /* Switch to RUN only for engine that were put in LOAD previously */
+ for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) {
+ if (LP55xx_MODE_ENGn_GET(i, mode, cfg->reg_op_mode.shift) != LP55xx_MODE_LOAD_ENG)
+ continue;
+
+ mode &= ~LP55xx_MODE_ENGn_MASK(i, cfg->reg_op_mode.shift);
+ mode |= LP55xx_MODE_RUN_ENG << LP55xx_MODE_ENGn_SHIFT(i, cfg->reg_op_mode.shift);
+ exec &= ~LP55xx_EXEC_ENGn_MASK(i, cfg->reg_exec.shift);
+ exec |= LP55xx_EXEC_RUN_ENG << LP55xx_EXEC_ENGn_SHIFT(i, cfg->reg_exec.shift);
+ }
+
+ lp55xx_write(chip, cfg->reg_op_mode.addr, mode);
+ lp55xx_wait_opmode_done(chip);
+ lp55xx_write(chip, cfg->reg_exec.addr, exec);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(lp55xx_run_engine_common);
+
static void lp55xx_reset_device(struct lp55xx_chip *chip)
{
const struct lp55xx_device_config *cfg = chip->cfg;
*/
struct lp55xx_device_config {
const struct lp55xx_reg reg_op_mode; /* addr, shift */
+ const struct lp55xx_reg reg_exec; /* addr, shift */
const struct lp55xx_reg engine_busy; /* addr, mask */
const struct lp55xx_reg reset;
const struct lp55xx_reg enable;
/* common chip functions */
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);
/* common probe/remove function */
extern int lp55xx_probe(struct i2c_client *client);
static void lp8501_run_engine(struct lp55xx_chip *chip, bool start)
{
- int ret;
- u8 mode;
- u8 exec;
-
/* stop engine */
if (!start) {
lp55xx_stop_all_engine(chip);
return;
}
- /*
- * To run the engine,
- * operation mode and enable register should updated at the same time
- */
-
- ret = lp55xx_read(chip, LP8501_REG_OP_MODE, &mode);
- if (ret)
- return;
-
- ret = lp55xx_read(chip, LP8501_REG_ENABLE, &exec);
- if (ret)
- return;
-
- /* change operation mode to RUN only when each engine is loading */
- if (LP8501_ENG1_IS_LOADING(mode)) {
- mode = (mode & ~LP8501_MODE_ENG1_M) | LP8501_RUN_ENG1;
- exec = (exec & ~LP8501_EXEC_ENG1_M) | LP8501_RUN_ENG1;
- }
-
- if (LP8501_ENG2_IS_LOADING(mode)) {
- mode = (mode & ~LP8501_MODE_ENG2_M) | LP8501_RUN_ENG2;
- exec = (exec & ~LP8501_EXEC_ENG2_M) | LP8501_RUN_ENG2;
- }
-
- if (LP8501_ENG3_IS_LOADING(mode)) {
- mode = (mode & ~LP8501_MODE_ENG3_M) | LP8501_RUN_ENG3;
- exec = (exec & ~LP8501_EXEC_ENG3_M) | LP8501_RUN_ENG3;
- }
-
- lp55xx_write(chip, LP8501_REG_OP_MODE, mode);
- lp8501_wait_opmode_done();
-
- lp55xx_update_bits(chip, LP8501_REG_ENABLE, LP8501_EXEC_M, exec);
+ lp55xx_run_engine_common(chip);
}
static int lp8501_update_program_memory(struct lp55xx_chip *chip,
.reg_op_mode = {
.addr = LP8501_REG_OP_MODE,
},
+ .reg_exec = {
+ .addr = LP8501_REG_ENABLE,
+ },
.engine_busy = {
.addr = LP8501_REG_STATUS,
.mask = LP8501_ENGINE_BUSY,