/*
 * Copyright (c) 2023 NXP Semiconductors
 * Copyright (c) 2023 Cognipilot Foundation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT onnn_ncp5623

/**
 * @file
 * @brief NCP5623 LED driver
 *
 * The NCP5623 is a 3-channel LED driver that communicates over I2C.
 */

#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/led.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(ncp5623, CONFIG_LED_LOG_LEVEL);

#define NCP5623_LED_CURRENT 0x20
#define NCP5623_LED_PWM0    0x40
#define NCP5623_LED_PWM1    0x60
#define NCP5623_LED_PWM2    0x80

#define NCP5623_CHANNEL_COUNT 3

/* Brightness limits */
#define NCP5623_MIN_BRIGHTNESS 0
#define NCP5623_MAX_BRIGHTNESS 0x1f

static const uint8_t led_channels[] = {NCP5623_LED_PWM0, NCP5623_LED_PWM1, NCP5623_LED_PWM2};

struct ncp5623_config {
	struct i2c_dt_spec bus;
	uint8_t num_leds;
	const struct led_info *leds_info;
};

static const struct led_info *ncp5623_led_to_info(const struct ncp5623_config *config, uint32_t led)
{
	if (led < config->num_leds) {
		return &config->leds_info[led];
	}

	return NULL;
}

static int ncp5623_get_info(const struct device *dev, uint32_t led, const struct led_info **info)
{
	const struct ncp5623_config *config = dev->config;
	const struct led_info *led_info = ncp5623_led_to_info(config, led);

	if (!led_info) {
		return -EINVAL;
	}

	*info = led_info;

	return 0;
}

static int ncp5623_set_color(const struct device *dev, uint32_t led, uint8_t num_colors,
			     const uint8_t *color)
{
	const struct ncp5623_config *config = dev->config;
	const struct led_info *led_info = ncp5623_led_to_info(config, led);
	uint8_t buf[6] = {0x70, NCP5623_LED_PWM0, 0x70, NCP5623_LED_PWM1, 0x70, NCP5623_LED_PWM2};

	if (!led_info) {
		return -ENODEV;
	}

	if (led_info->num_colors != 3) {
		return -ENOTSUP;
	}
	if (num_colors != 3) {
		return -EINVAL;
	}

	buf[1] = buf[1] | color[0] / 8;
	buf[3] = buf[3] | color[1] / 8;
	buf[5] = buf[5] | color[2] / 8;

	return i2c_burst_write_dt(&config->bus, NCP5623_LED_CURRENT | NCP5623_MAX_BRIGHTNESS, buf,
				  sizeof(buf));
}

static int ncp5623_set_brightness(const struct device *dev, uint32_t led, uint8_t value)
{
	const struct ncp5623_config *config = dev->config;
	const struct led_info *led_info = ncp5623_led_to_info(config, led);
	int ret = 0;

	if (!led_info) {
		return -ENODEV;
	}

	if (value > 100) {
		return -EINVAL;
	}

	if (led_info->num_colors != 1) {
		return -ENOTSUP;
	}

	/* Rescale 0..100 to 0..31 */
	value = value * NCP5623_MAX_BRIGHTNESS / 100;

	ret = i2c_reg_write_byte_dt(&config->bus, led_channels[led] | value, 0x70);

	if (ret < 0) {
		LOG_ERR("%s: LED write failed", dev->name);
	}

	return ret;
}

static inline int ncp5623_led_on(const struct device *dev, uint32_t led)
{
	return ncp5623_set_brightness(dev, led, 100);
}

static inline int ncp5623_led_off(const struct device *dev, uint32_t led)
{
	return ncp5623_set_brightness(dev, led, 0);
}

static int ncp5623_led_init(const struct device *dev)
{
	const struct ncp5623_config *config = dev->config;
	const struct led_info *led_info = NULL;
	int i;
	uint8_t buf[6] = {0x70, NCP5623_LED_PWM0, 0x70, NCP5623_LED_PWM1, 0x70, NCP5623_LED_PWM2};

	if (!i2c_is_ready_dt(&config->bus)) {
		LOG_ERR("%s: I2C device not ready", dev->name);
		return -ENODEV;
	}

	if (config->num_leds == 1) { /* one three-channel (RGB) LED */
		led_info = ncp5623_led_to_info(config, 0);

		if (!led_info) {
			return -ENODEV;
		}

		if (led_info->num_colors != 3 || led_info->num_colors != 1) {
			LOG_ERR("%s: invalid number of colors %d (must be %d or 1)", dev->name,
				led_info->num_colors, NCP5623_CHANNEL_COUNT);
		}
	} else if (config->num_leds <= 3) { /* three single-channel LEDs */
		for (i = 0; i < config->num_leds; i++) {
			led_info = ncp5623_led_to_info(config, 0);

			if (!led_info) {
				return -ENODEV;
			}

			if (led_info->num_colors > 1) {
				LOG_ERR("%s: invalid number of colors %d (must be 1 when defining "
					"multiple leds)",
					dev->name, led_info->num_colors);
				return -EINVAL;
			}
		}
	} else {
		LOG_ERR("%s: invalid number of leds %d (max %d)", dev->name, config->num_leds,
			NCP5623_CHANNEL_COUNT);
		return -EINVAL;
	}

	if (i2c_burst_write_dt(&config->bus, NCP5623_LED_CURRENT | NCP5623_MAX_BRIGHTNESS, buf,
			       6)) {
		LOG_ERR("%s: LED write failed", dev->name);
		return -EIO;
	}

	return 0;
}

static const struct led_driver_api ncp5623_led_api = {
	.set_brightness = ncp5623_set_brightness,
	.on = ncp5623_led_on,
	.off = ncp5623_led_off,
	.get_info = ncp5623_get_info,
	.set_color = ncp5623_set_color,
};

#define COLOR_MAPPING(led_node_id)                                                                 \
	static const uint8_t color_mapping_##led_node_id[] = DT_PROP(led_node_id, color_mapping);

#define LED_INFO(led_node_id)                                                                      \
	{                                                                                          \
		.label = DT_PROP(led_node_id, label),                                              \
		.index = DT_PROP(led_node_id, index),                                              \
		.num_colors = DT_PROP_LEN(led_node_id, color_mapping),                             \
		.color_mapping = color_mapping_##led_node_id,                                      \
	},

#define NCP5623_DEFINE(id)                                                                         \
                                                                                                   \
	DT_INST_FOREACH_CHILD(id, COLOR_MAPPING)                                                   \
                                                                                                   \
	static const struct led_info ncp5623_leds_##id[] = {DT_INST_FOREACH_CHILD(id, LED_INFO)};  \
                                                                                                   \
	static const struct ncp5623_config ncp5623_config_##id = {                                 \
		.bus = I2C_DT_SPEC_INST_GET(id),                                                   \
		.num_leds = ARRAY_SIZE(ncp5623_leds_##id),                                         \
		.leds_info = ncp5623_leds_##id,                                                    \
	};                                                                                         \
	DEVICE_DT_INST_DEFINE(id, &ncp5623_led_init, NULL, NULL, &ncp5623_config_##id,             \
			      POST_KERNEL, CONFIG_LED_INIT_PRIORITY, &ncp5623_led_api);

DT_INST_FOREACH_STATUS_OKAY(NCP5623_DEFINE)
