3232
3333#include <zephyr/drivers/i2c.h>
3434#include <zephyr/drivers/led.h>
35+ #include <zephyr/drivers/gpio.h>
3536#include <zephyr/device.h>
3637#include <zephyr/kernel.h>
3738
@@ -86,8 +87,10 @@ LOG_MODULE_REGISTER(lp5562);
8687#define LP5562_MAX_CURRENT_SETTING 255
8788
8889/* Values for ENABLE register. */
89- #define LP5562_ENABLE_CHIP_EN (1 << 6)
90- #define LP5562_ENABLE_LOG_EN (1 << 7)
90+ #define LP5562_ENABLE_CHIP_EN_MASK (1 << 6)
91+ #define LP5562_ENABLE_CHIP_EN_SET (1 << 6)
92+ #define LP5562_ENABLE_CHIP_EN_CLR (0 << 6)
93+ #define LP5562_ENABLE_LOG_EN (1 << 7)
9194
9295/* Values for CONFIG register. */
9396#define LP5562_CONFIG_EXTERNAL_CLOCK 0x00
@@ -167,6 +170,7 @@ struct lp5562_config {
167170 uint8_t g_current ;
168171 uint8_t b_current ;
169172 uint8_t w_current ;
173+ struct gpio_dt_spec enable_gpio ;
170174};
171175
172176struct lp5562_data {
@@ -933,18 +937,75 @@ static int lp5562_led_update_current(const struct device *dev)
933937 return ret ;
934938}
935939
940+ static int lp5562_enable (const struct device * dev )
941+ {
942+ const struct lp5562_config * config = dev -> config ;
943+ const struct gpio_dt_spec * enable_gpio = & config -> enable_gpio ;
944+ int err = 0 ;
945+
946+ /* If ENABLE_GPIO control is enabled, we need to assert ENABLE_GPIO first. */
947+ if (enable_gpio -> port != NULL ) {
948+ err = gpio_pin_set_dt (enable_gpio , 1 );
949+ if (err ) {
950+ LOG_ERR ("%s: failed to set enable GPIO 1" , dev -> name );
951+ return err ;
952+ }
953+ /*
954+ * The I2C host should allow at least 1ms before sending data to
955+ * the LP5562 after the rising edge of the enable line.
956+ * So let's wait for 1 ms.
957+ */
958+ k_sleep (K_MSEC (1 ));
959+ }
960+
961+ /* Reset all internal registers to have a deterministic state. */
962+ err = i2c_reg_write_byte_dt (& config -> bus , LP5562_RESET , 0xFF );
963+ if (err ) {
964+ LOG_ERR ("%s: failed to soft-reset device" , dev -> name );
965+ return err ;
966+ }
967+
968+ /* Set en bit in LP5562_ENABLE register. */
969+ err = i2c_reg_update_byte_dt (& config -> bus , LP5562_ENABLE , LP5562_ENABLE_CHIP_EN_MASK ,
970+ LP5562_ENABLE_CHIP_EN_SET );
971+ if (err ) {
972+ LOG_ERR ("%s: failed to set EN Bit in ENABLE register" , dev -> name );
973+ return err ;
974+ }
975+ /* Allow 500 µs delay after setting chip_en bit to '1'. */
976+ k_sleep (K_USEC (500 ));
977+ return 0 ;
978+ }
979+
936980static int lp5562_led_init (const struct device * dev )
937981{
938982 const struct lp5562_config * config = dev -> config ;
939983 struct lp5562_data * data = dev -> data ;
940984 struct led_data * dev_data = & data -> dev_data ;
985+ const struct gpio_dt_spec * enable_gpio = & config -> enable_gpio ;
941986 int ret ;
942987
988+ if (enable_gpio -> port != NULL ) {
989+ if (!gpio_is_ready_dt (enable_gpio )) {
990+ return - ENODEV ;
991+ }
992+ ret = gpio_pin_configure_dt (enable_gpio , GPIO_OUTPUT );
993+ if (ret ) {
994+ LOG_ERR ("LP5562 Enable GPIO Config failed" );
995+ return ret ;
996+ }
997+ }
998+
943999 if (!device_is_ready (config -> bus .bus )) {
9441000 LOG_ERR ("I2C device not ready" );
9451001 return - ENODEV ;
9461002 }
9471003
1004+ ret = lp5562_enable (dev );
1005+ if (ret ) {
1006+ return ret ;
1007+ }
1008+
9481009 /* Hardware specific limits */
9491010 dev_data -> min_period = LP5562_MIN_BLINK_PERIOD ;
9501011 dev_data -> max_period = LP5562_MAX_BLINK_PERIOD ;
@@ -957,12 +1018,6 @@ static int lp5562_led_init(const struct device *dev)
9571018 return ret ;
9581019 }
9591020
960- if (i2c_reg_write_byte_dt (& config -> bus , LP5562_ENABLE ,
961- LP5562_ENABLE_CHIP_EN )) {
962- LOG_ERR ("Enabling LP5562 LED chip failed." );
963- return - EIO ;
964- }
965-
9661021 if (i2c_reg_write_byte_dt (& config -> bus , LP5562_CONFIG ,
9671022 (LP5562_CONFIG_INTERNAL_CLOCK |
9681023 LP5562_CONFIG_PWRSAVE_EN ))) {
@@ -1005,6 +1060,7 @@ static const struct led_driver_api lp5562_led_api = {
10051060 .g_current = DT_INST_PROP(id, green_output_current), \
10061061 .b_current = DT_INST_PROP(id, blue_output_current), \
10071062 .w_current = DT_INST_PROP(id, white_output_current), \
1063+ .enable_gpio = GPIO_DT_SPEC_INST_GET_OR(id, enable_gpios, {0}), \
10081064 }; \
10091065 \
10101066 struct lp5562_data lp5562_data_##id; \
0 commit comments