Lines Matching +full:led +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0-only
3 * lp5523.c - LP5523, LP55231 LED Driver
19 #include <linux/platform_data/leds-lp55xx.h>
22 #include "leds-lp55xx-common.h"
82 #define LP5523_MODE_ENG1_M 0x30 /* Operation Mode Register */
89 #define LP5523_ENG1_IS_LOADING(mode) \ argument
90 ((mode & LP5523_MODE_ENG1_M) == LP5523_LOAD_ENG1)
91 #define LP5523_ENG2_IS_LOADING(mode) \ argument
92 ((mode & LP5523_MODE_ENG2_M) == LP5523_LOAD_ENG2)
93 #define LP5523_ENG3_IS_LOADING(mode) \ argument
94 ((mode & LP5523_MODE_ENG3_M) == LP5523_LOAD_ENG3)
104 #define LED_ACTIVE(mux, led) (!!(mux & (0x0001 << led))) argument
118 static void lp5523_set_led_current(struct lp55xx_led *led, u8 led_current) in lp5523_set_led_current() argument
120 led->led_current = led_current; in lp5523_set_led_current()
121 lp55xx_write(led->chip, LP5523_REG_LED_CURRENT_BASE + led->chan_nr, in lp5523_set_led_current()
133 /* Chip startup time is 500 us, 1 - 2 ms gives some margin */ in lp5523_post_init_device()
157 enum lp55xx_engine_index idx = chip->engine_idx; in lp5523_load_engine()
177 enum lp55xx_engine_index idx = chip->engine_idx; in lp5523_load_engine_and_select_page()
197 enum lp55xx_engine_index idx = chip->engine_idx; in lp5523_stop_engine()
220 u8 mode; in lp5523_run_engine() local
232 * operation mode and enable register should updated at the same time in lp5523_run_engine()
235 ret = lp55xx_read(chip, LP5523_REG_OP_MODE, &mode); in lp5523_run_engine()
243 /* change operation mode to RUN only when each engine is loading */ in lp5523_run_engine()
244 if (LP5523_ENG1_IS_LOADING(mode)) { in lp5523_run_engine()
245 mode = (mode & ~LP5523_MODE_ENG1_M) | LP5523_RUN_ENG1; in lp5523_run_engine()
249 if (LP5523_ENG2_IS_LOADING(mode)) { in lp5523_run_engine()
250 mode = (mode & ~LP5523_MODE_ENG2_M) | LP5523_RUN_ENG2; in lp5523_run_engine()
254 if (LP5523_ENG3_IS_LOADING(mode)) { in lp5523_run_engine()
255 mode = (mode & ~LP5523_MODE_ENG3_M) | LP5523_RUN_ENG3; in lp5523_run_engine()
259 lp55xx_write(chip, LP5523_REG_OP_MODE, mode); in lp5523_run_engine()
271 /* one pattern per engine setting LED MUX start and stop addresses */ in lp5523_init_program_engine()
291 /* write LED MUX address space for each engine */ in lp5523_init_program_engine()
293 chip->engine_idx = i; in lp5523_init_program_engine()
298 pattern[i - 1][j]); in lp5523_init_program_engine()
314 dev_err(&chip->cl->dev, in lp5523_init_program_engine()
315 "could not configure LED engine, status = 0x%.2x\n", in lp5523_init_program_engine()
317 ret = -1; in lp5523_init_program_engine()
336 while ((offset < size - 1) && (i < LP5523_PROGRAM_LENGTH)) { in lp5523_update_program_memory()
358 return -EINVAL; in lp5523_update_program_memory()
364 dev_err(&chip->cl->dev, "wrong pattern format\n"); in lp5523_update_program_memory()
365 return -EINVAL; in lp5523_update_program_memory()
370 const struct firmware *fw = chip->fw; in lp5523_firmware_loaded()
372 if (fw->size > LP5523_PROGRAM_LENGTH) { in lp5523_firmware_loaded()
373 dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n", in lp5523_firmware_loaded()
374 fw->size); in lp5523_firmware_loaded()
380 * 1) set engine mode to "LOAD" in lp5523_firmware_loaded()
385 lp5523_update_program_memory(chip, fw->data, fw->size); in lp5523_firmware_loaded()
392 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); in show_engine_mode() local
393 struct lp55xx_chip *chip = led->chip; in show_engine_mode()
394 enum lp55xx_engine_mode mode = chip->engines[nr - 1].mode; in show_engine_mode() local
396 switch (mode) { in show_engine_mode()
414 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); in store_engine_mode() local
415 struct lp55xx_chip *chip = led->chip; in store_engine_mode()
416 struct lp55xx_engine *engine = &chip->engines[nr - 1]; in store_engine_mode()
418 mutex_lock(&chip->lock); in store_engine_mode()
420 chip->engine_idx = nr; in store_engine_mode()
424 engine->mode = LP55XX_ENGINE_RUN; in store_engine_mode()
428 engine->mode = LP55XX_ENGINE_LOAD; in store_engine_mode()
431 engine->mode = LP55XX_ENGINE_DISABLED; in store_engine_mode()
434 mutex_unlock(&chip->lock); in store_engine_mode()
460 return -1; in lp5523_mux_parse()
482 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); in show_engine_leds() local
483 struct lp55xx_chip *chip = led->chip; in show_engine_leds()
486 lp5523_mux_to_array(chip->engines[nr - 1].led_mux, mux); in show_engine_leds()
496 struct lp55xx_engine *engine = &chip->engines[nr - 1]; in lp5523_load_mux()
518 engine->led_mux = mux; in lp5523_load_mux()
526 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); in store_engine_leds() local
527 struct lp55xx_chip *chip = led->chip; in store_engine_leds()
528 struct lp55xx_engine *engine = &chip->engines[nr - 1]; in store_engine_leds()
533 return -EINVAL; in store_engine_leds()
535 mutex_lock(&chip->lock); in store_engine_leds()
537 chip->engine_idx = nr; in store_engine_leds()
538 ret = -EINVAL; in store_engine_leds()
540 if (engine->mode != LP55XX_ENGINE_LOAD) in store_engine_leds()
548 mutex_unlock(&chip->lock); in store_engine_leds()
559 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); in store_engine_load() local
560 struct lp55xx_chip *chip = led->chip; in store_engine_load()
563 mutex_lock(&chip->lock); in store_engine_load()
565 chip->engine_idx = nr; in store_engine_load()
569 mutex_unlock(&chip->lock); in store_engine_load()
581 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); in lp5523_selftest() local
582 struct lp55xx_chip *chip = led->chip; in lp5523_selftest()
583 struct lp55xx_platform_data *pdata = chip->pdata; in lp5523_selftest()
587 mutex_lock(&chip->lock); in lp5523_selftest()
594 if (pdata->clock_mode == LP55XX_CLOCK_EXT) { in lp5523_selftest()
613 vdd--; /* There may be some fluctuation in measurement */ in lp5523_selftest()
616 /* Skip non-existing channels */ in lp5523_selftest()
617 if (pdata->led_config[i].led_current == 0) in lp5523_selftest()
622 pdata->led_config[i].led_current); in lp5523_selftest()
625 /* let current stabilize 2 - 4ms before measurements start */ in lp5523_selftest()
643 pos += sprintf(buf + pos, "LED %d FAIL\n", i); in lp5523_selftest()
649 led->led_current); in lp5523_selftest()
650 led++; in lp5523_selftest()
659 mutex_unlock(&chip->lock); in lp5523_selftest()
684 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); in show_master_fader() local
685 struct lp55xx_chip *chip = led->chip; in show_master_fader()
689 mutex_lock(&chip->lock); in show_master_fader()
690 ret = lp55xx_read(chip, LP5523_REG_MASTER_FADER_BASE + nr - 1, &val); in show_master_fader()
691 mutex_unlock(&chip->lock); in show_master_fader()
706 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); in store_master_fader() local
707 struct lp55xx_chip *chip = led->chip; in store_master_fader()
712 return -EINVAL; in store_master_fader()
715 return -EINVAL; in store_master_fader()
717 mutex_lock(&chip->lock); in store_master_fader()
718 ret = lp55xx_write(chip, LP5523_REG_MASTER_FADER_BASE + nr - 1, in store_master_fader()
720 mutex_unlock(&chip->lock); in store_master_fader()
735 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); in show_master_fader_leds() local
736 struct lp55xx_chip *chip = led->chip; in show_master_fader_leds()
740 mutex_lock(&chip->lock); in show_master_fader_leds()
750 ret = -EINVAL; in show_master_fader_leds()
758 mutex_unlock(&chip->lock); in show_master_fader_leds()
766 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); in store_master_fader_leds() local
767 struct lp55xx_chip *chip = led->chip; in store_master_fader_leds()
773 mutex_lock(&chip->lock); in store_master_fader_leds()
777 val = (buf[i] - '0') << LP5523_FADER_MAPPING_SHIFT; in store_master_fader_leds()
785 ret = -EINVAL; in store_master_fader_leds()
791 mutex_unlock(&chip->lock); in store_master_fader_leds()
795 static int lp5523_multicolor_brightness(struct lp55xx_led *led) in lp5523_multicolor_brightness() argument
797 struct lp55xx_chip *chip = led->chip; in lp5523_multicolor_brightness()
801 mutex_lock(&chip->lock); in lp5523_multicolor_brightness()
802 for (i = 0; i < led->mc_cdev.num_colors; i++) { in lp5523_multicolor_brightness()
805 led->mc_cdev.subled_info[i].channel, in lp5523_multicolor_brightness()
806 led->mc_cdev.subled_info[i].brightness); in lp5523_multicolor_brightness()
810 mutex_unlock(&chip->lock); in lp5523_multicolor_brightness()
814 static int lp5523_led_brightness(struct lp55xx_led *led) in lp5523_led_brightness() argument
816 struct lp55xx_chip *chip = led->chip; in lp5523_led_brightness()
819 mutex_lock(&chip->lock); in lp5523_led_brightness()
820 ret = lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr, in lp5523_led_brightness()
821 led->brightness); in lp5523_led_brightness()
822 mutex_unlock(&chip->lock); in lp5523_led_brightness()
892 struct lp55xx_led *led; in lp5523_probe() local
893 struct lp55xx_platform_data *pdata = dev_get_platdata(&client->dev); in lp5523_probe()
894 struct device_node *np = dev_of_node(&client->dev); in lp5523_probe()
896 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); in lp5523_probe()
898 return -ENOMEM; in lp5523_probe()
900 chip->cfg = &lp5523_cfg; in lp5523_probe()
904 pdata = lp55xx_of_populate_pdata(&client->dev, np, in lp5523_probe()
909 dev_err(&client->dev, "no platform data\n"); in lp5523_probe()
910 return -EINVAL; in lp5523_probe()
914 led = devm_kcalloc(&client->dev, in lp5523_probe()
915 pdata->num_channels, sizeof(*led), GFP_KERNEL); in lp5523_probe()
916 if (!led) in lp5523_probe()
917 return -ENOMEM; in lp5523_probe()
919 chip->cl = client; in lp5523_probe()
920 chip->pdata = pdata; in lp5523_probe()
922 mutex_init(&chip->lock); in lp5523_probe()
924 i2c_set_clientdata(client, led); in lp5523_probe()
930 dev_info(&client->dev, "%s Programmable led chip found\n", id->name); in lp5523_probe()
932 ret = lp55xx_register_leds(led, chip); in lp5523_probe()
938 dev_err(&client->dev, "registering sysfs failed\n"); in lp5523_probe()
952 struct lp55xx_led *led = i2c_get_clientdata(client); in lp5523_remove() local
953 struct lp55xx_chip *chip = led->chip; in lp5523_remove()
992 MODULE_DESCRIPTION("LP5523 LED engine");