From 99751b1d98cfe8a6daaa765f46894b1666478a7f Mon Sep 17 00:00:00 2001 From: Jonas Remmert Date: Mon, 29 May 2023 23:04:48 +0200 Subject: [PATCH] drivers: led: Add lp5569 led controller driver Add a minimal driver for the ti lp5569 led controller. The driver supports multiple instances. Commands on|off|set_brightness are supported. Signed-off-by: Jonas Remmert --- drivers/led/CMakeLists.txt | 1 + drivers/led/Kconfig | 1 + drivers/led/Kconfig.lp5569 | 11 +++ drivers/led/lp5569.c | 121 ++++++++++++++++++++++++++++++++ dts/bindings/led/ti,lp5569.yaml | 5 ++ 5 files changed, 139 insertions(+) create mode 100644 drivers/led/Kconfig.lp5569 create mode 100644 drivers/led/lp5569.c create mode 100644 dts/bindings/led/ti,lp5569.yaml diff --git a/drivers/led/CMakeLists.txt b/drivers/led/CMakeLists.txt index c9a7478286d..e018acb0cae 100644 --- a/drivers/led/CMakeLists.txt +++ b/drivers/led/CMakeLists.txt @@ -11,6 +11,7 @@ zephyr_library_sources_ifdef(CONFIG_LED_XEC led_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_LP3943 lp3943.c) zephyr_library_sources_ifdef(CONFIG_LP503X lp503x.c) zephyr_library_sources_ifdef(CONFIG_LP5562 lp5562.c) +zephyr_library_sources_ifdef(CONFIG_LP5569 lp5569.c) zephyr_library_sources_ifdef(CONFIG_PCA9633 pca9633.c) zephyr_library_sources_ifdef(CONFIG_TLC59108 tlc59108.c) diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig index 7c4f5ced086..bf606b6e91b 100644 --- a/drivers/led/Kconfig +++ b/drivers/led/Kconfig @@ -31,6 +31,7 @@ source "drivers/led/Kconfig.ht16k33" source "drivers/led/Kconfig.lp3943" source "drivers/led/Kconfig.lp503x" source "drivers/led/Kconfig.lp5562" +source "drivers/led/Kconfig.lp5569" source "drivers/led/Kconfig.pca9633" source "drivers/led/Kconfig.pwm" source "drivers/led/Kconfig.tlc59108" diff --git a/drivers/led/Kconfig.lp5569 b/drivers/led/Kconfig.lp5569 new file mode 100644 index 00000000000..1090993399a --- /dev/null +++ b/drivers/led/Kconfig.lp5569 @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Phytec Messtechnik GmbH +# SPDX-License-Identifier: Apache-2.0 + +config LP5569 + bool "LP5569 LED driver" + default y + depends on DT_HAS_TI_LP5569_ENABLED + select I2C + help + Enable LED driver for LP5569. LP5569 LED driver has 9 channels. + Each channel can drive up to 25.5 mA per LED. diff --git a/drivers/led/lp5569.c b/drivers/led/lp5569.c new file mode 100644 index 00000000000..f3f196785df --- /dev/null +++ b/drivers/led/lp5569.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2023 Phytec Messtechnik GmbH. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_lp5569 + +/** + * @file + * @brief LP5569 LED controller + * + * The LP5569 is a 9-channel LED driver that communicates over I2C. + */ + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(lp5569, CONFIG_LED_LOG_LEVEL); + +#define LP5569_NUM_LEDS 9 + +/* General Registers */ +#define LP5569_CONFIG 0x00 +#define LP5569_CHIP_EN BIT(6) + +#define LP5569_MISC 0x2F +#define LP5569_POWERSAVE_EN BIT(5) + +/* PWM base Register for controlling the duty-cycle */ +#define LP5569_LED0_PWM 0x16 + +struct lp5569_config { + struct i2c_dt_spec bus; +}; + +static int lp5569_led_set_brightness(const struct device *dev, uint32_t led, + uint8_t brightness) +{ + const struct lp5569_config *config = dev->config; + uint8_t val; + int ret; + + if (led >= LP5569_NUM_LEDS || brightness > 100) { + return -EINVAL; + } + + /* Map 0-100 % to 0-255 pwm register value */ + val = brightness * 255 / 100; + + ret = i2c_reg_write_byte_dt(&config->bus, LP5569_LED0_PWM + led, val); + if (ret < 0) { + LOG_ERR("LED reg update failed"); + return ret; + } + + return 0; +} + +static inline int lp5569_led_on(const struct device *dev, uint32_t led) +{ + /* Set LED brightness to 100 % */ + return lp5569_led_set_brightness(dev, led, 100); +} + +static inline int lp5569_led_off(const struct device *dev, uint32_t led) +{ + /* Set LED brightness to 0 % */ + return lp5569_led_set_brightness(dev, led, 0); +} + +static int lp5569_init(const struct device *dev) +{ + const struct lp5569_config *config = dev->config; + int ret; + + if (!i2c_is_ready_dt(&config->bus)) { + LOG_ERR("I2C device not ready"); + return -ENODEV; + } + + ret = i2c_reg_write_byte_dt(&config->bus, LP5569_CONFIG, + LP5569_CHIP_EN); + if (ret < 0) { + LOG_ERR("Enable LP5569 failed"); + return ret; + } + + ret = i2c_reg_write_byte_dt(&config->bus, LP5569_MISC, + LP5569_POWERSAVE_EN); + if (ret < 0) { + LOG_ERR("LED reg update failed"); + return ret; + } + + return 0; +} + + +static const struct led_driver_api lp5569_led_api = { + .set_brightness = lp5569_led_set_brightness, + .on = lp5569_led_on, + .off = lp5569_led_off, +}; + +#define LP5569_DEFINE(id) \ + static const struct lp5569_config lp5569_config_##id = { \ + .bus = I2C_DT_SPEC_INST_GET(id), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(id, &lp5569_init, \ + NULL, \ + NULL, \ + &lp5569_config_##id, POST_KERNEL, \ + CONFIG_LED_INIT_PRIORITY, \ + &lp5569_led_api); + +DT_INST_FOREACH_STATUS_OKAY(LP5569_DEFINE) diff --git a/dts/bindings/led/ti,lp5569.yaml b/dts/bindings/led/ti,lp5569.yaml new file mode 100644 index 00000000000..1d84ba257c5 --- /dev/null +++ b/dts/bindings/led/ti,lp5569.yaml @@ -0,0 +1,5 @@ +description: TI LP5569 LED + +compatible: "ti,lp5569" + +include: i2c-device.yaml