drivers: led: lp50xx: add reset
The LP50XX family has a specific register to reset the configuration to default state from any other state. Use this instead of relying on the manual configuration of registers during startup. Based on initial work from: Marek Janus <marek.janus@grinn-global.com> Signed-off-by: Mathieu Anquetin <mathieu.anquetin@groupe-cahors.com>
This commit is contained in:
parent
6efe55b8f4
commit
3c1b4d0a1f
1 changed files with 37 additions and 27 deletions
|
@ -56,6 +56,9 @@ LOG_MODULE_REGISTER(lp50xx, CONFIG_LED_LOG_LEVEL);
|
||||||
#define LP50XX_OUT0_COLOR(nmodules) \
|
#define LP50XX_OUT0_COLOR(nmodules) \
|
||||||
(LP50XX_LED0_BRIGHTNESS(nmodules) + (nmodules))
|
(LP50XX_LED0_BRIGHTNESS(nmodules) + (nmodules))
|
||||||
|
|
||||||
|
#define LP50XX_RESET(nmodules) \
|
||||||
|
(LP50XX_OUT0_COLOR(nmodules) + LP50XX_COLORS_PER_LED * (nmodules))
|
||||||
|
|
||||||
/* Register values */
|
/* Register values */
|
||||||
#define CONFIG0_CHIP_EN BIT(6)
|
#define CONFIG0_CHIP_EN BIT(6)
|
||||||
|
|
||||||
|
@ -66,6 +69,8 @@ LOG_MODULE_REGISTER(lp50xx, CONFIG_LED_LOG_LEVEL);
|
||||||
#define CONFIG1_POWER_SAVE_EN BIT(4)
|
#define CONFIG1_POWER_SAVE_EN BIT(4)
|
||||||
#define CONFIG1_LOG_SCALE_EN BIT(5)
|
#define CONFIG1_LOG_SCALE_EN BIT(5)
|
||||||
|
|
||||||
|
#define RESET_SW 0xFF
|
||||||
|
|
||||||
struct lp50xx_config {
|
struct lp50xx_config {
|
||||||
struct i2c_dt_spec bus;
|
struct i2c_dt_spec bus;
|
||||||
uint8_t num_modules;
|
uint8_t num_modules;
|
||||||
|
@ -200,6 +205,34 @@ static int lp50xx_write_channels(const struct device *dev,
|
||||||
return i2c_write_dt(&config->bus, data->chan_buf, num_channels + 1);
|
return i2c_write_dt(&config->bus, data->chan_buf, num_channels + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lp50xx_reset(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct lp50xx_config *config = dev->config;
|
||||||
|
uint8_t buf[2];
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* Software reset */
|
||||||
|
buf[0] = LP50XX_RESET(config->num_modules);
|
||||||
|
buf[1] = RESET_SW;
|
||||||
|
err = i2c_write_dt(&config->bus, buf, 2);
|
||||||
|
if (err < 0) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* After reset, apply configuration since all registers are reset. */
|
||||||
|
buf[0] = LP50XX_DEVICE_CONFIG1;
|
||||||
|
buf[1] = CONFIG1_PWM_DITHERING_EN | CONFIG1_AUTO_INCR_EN
|
||||||
|
| CONFIG1_POWER_SAVE_EN;
|
||||||
|
if (config->max_curr_opt) {
|
||||||
|
buf[1] |= CONFIG1_MAX_CURRENT_OPT;
|
||||||
|
}
|
||||||
|
if (config->log_scale_en) {
|
||||||
|
buf[1] |= CONFIG1_LOG_SCALE_EN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i2c_write_dt(&config->bus, buf, 2);
|
||||||
|
}
|
||||||
|
|
||||||
static int lp50xx_init(const struct device *dev)
|
static int lp50xx_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct lp50xx_config *config = dev->config;
|
const struct lp50xx_config *config = dev->config;
|
||||||
|
@ -219,22 +252,10 @@ static int lp50xx_init(const struct device *dev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Reset device */
|
||||||
* Since the status of the LP503x controller is unknown when entering
|
err = lp50xx_reset(dev);
|
||||||
* this function, and since there is no way to reset it, then the whole
|
|
||||||
* configuration must be applied.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Disable bank control for all LEDs. */
|
|
||||||
buf[0] = LP50XX_LED_CONFIG0;
|
|
||||||
buf[1] = 0;
|
|
||||||
buf[2] = 0;
|
|
||||||
if (config->chip == LP5009 || config->chip == LP5012) {
|
|
||||||
err = i2c_write_dt(&config->bus, buf, 2);
|
|
||||||
} else {
|
|
||||||
err = i2c_write_dt(&config->bus, buf, 3);
|
|
||||||
}
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
LOG_ERR("%s: failed to reset", dev->name);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,18 +267,7 @@ static int lp50xx_init(const struct device *dev)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply configuration. */
|
return 0;
|
||||||
buf[0] = LP50XX_DEVICE_CONFIG1;
|
|
||||||
buf[1] = CONFIG1_PWM_DITHERING_EN | CONFIG1_AUTO_INCR_EN
|
|
||||||
| CONFIG1_POWER_SAVE_EN;
|
|
||||||
if (config->max_curr_opt) {
|
|
||||||
buf[1] |= CONFIG1_MAX_CURRENT_OPT;
|
|
||||||
}
|
|
||||||
if (config->log_scale_en) {
|
|
||||||
buf[1] |= CONFIG1_LOG_SCALE_EN;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i2c_write_dt(&config->bus, buf, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct led_driver_api lp50xx_led_api = {
|
static const struct led_driver_api lp50xx_led_api = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue