/*
 * 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 <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/led.h>
#include <zephyr/device.h>
#include <zephyr/pm/device.h>
#include <zephyr/kernel.h>

#include <zephyr/logging/log.h>
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)
#define LP5569_CP_MODE_SHIFT 3

/* PWM base Register for controlling the duty-cycle */
#define LP5569_LED0_PWM 0x16

struct lp5569_config {
	struct i2c_dt_spec bus;
	struct gpio_dt_spec enable_gpio;
	const uint8_t cp_mode;
};

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_enable(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;
	}

	/* flip the enable pin if specified */
	if (config->enable_gpio.port) {
		if (!gpio_is_ready_dt(&config->enable_gpio)) {
			LOG_ERR("Enable GPIO not ready");
			return -ENODEV;
		}

		ret = gpio_pin_configure_dt(&config->enable_gpio, GPIO_OUTPUT_ACTIVE);
		if (ret < 0) {
			LOG_ERR("Failed to configure enable_gpio, err: %d", ret);
			return ret;
		}

		/* datasheet 7.9: t_en max 3 ms for chip initialization */
		k_msleep(3);
	}

	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 |
					    (config->cp_mode << LP5569_CP_MODE_SHIFT));
	if (ret < 0) {
		LOG_ERR("LED reg update failed");
		return ret;
	}

	return 0;
}

static int lp5569_init(const struct device *dev)
{
	/* If the device is behind a power domain, it will start in
	 * PM_DEVICE_STATE_OFF.
	 */
	if (pm_device_on_power_domain(dev)) {
		pm_device_init_off(dev);
		LOG_INF("Init %s as PM_DEVICE_STATE_OFF", dev->name);
		return 0;
	}

	return lp5569_enable(dev);
}

#ifdef CONFIG_PM_DEVICE
static int lp5569_pm_action(const struct device *dev, enum pm_device_action action)
{
	const struct lp5569_config *config = dev->config;
	int ret;

	switch (action) {
	case PM_DEVICE_ACTION_TURN_ON:
	case PM_DEVICE_ACTION_RESUME:
		ret = lp5569_enable(dev);
		if (ret < 0) {
			LOG_ERR("Enable LP5569 failed");
			return ret;
		}
		break;
	case PM_DEVICE_ACTION_TURN_OFF:
	case PM_DEVICE_ACTION_SUSPEND:
		ret = i2c_reg_update_byte_dt(&config->bus, LP5569_CONFIG, LP5569_CHIP_EN, 0);
		if (ret < 0) {
			LOG_ERR("Disable LP5569 failed");
			return ret;
		}
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}
#endif /* CONFIG_PM_DEVICE */

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),                                                   \
		.enable_gpio = GPIO_DT_SPEC_INST_GET_OR(id, enable_gpios, {0}),                    \
		.cp_mode = DT_ENUM_IDX(DT_DRV_INST(id), charge_pump_mode),                         \
	};                                                                                         \
                                                                                                   \
	PM_DEVICE_DT_INST_DEFINE(id, lp5569_pm_action);                                            \
                                                                                                   \
	DEVICE_DT_INST_DEFINE(id, &lp5569_init, PM_DEVICE_DT_INST_GET(id), NULL,                   \
			      &lp5569_config_##id, POST_KERNEL, CONFIG_LED_INIT_PRIORITY,          \
			      &lp5569_led_api);

DT_INST_FOREACH_STATUS_OKAY(LP5569_DEFINE)
