/*
 * Copyright (c) 2020 Seagate Technology LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ti_lp503x

/**
 * @file
 * @brief LP503x LED controller
 */

#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/led.h>
#include <zephyr/drivers/led/lp503x.h>
#include <zephyr/device.h>
#include <zephyr/zephyr.h>

#define LOG_LEVEL CONFIG_LED_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(lp503x);

#define LP503X_DEVICE_CONFIG0		0
#define   CONFIG0_CHIP_EN		BIT(6)

#define LP503X_DEVICE_CONFIG1		0x1
#define   CONFIG1_LED_GLOBAL_OFF	BIT(0)
#define   CONFIG1_MAX_CURRENT_OPT	BIT(1)
#define   CONFIG1_PWM_DITHERING_EN	BIT(2)
#define   CONFIG1_AUTO_INCR_EN		BIT(3)
#define   CONFIG1_POWER_SAVE_EN		BIT(4)
#define   CONFIG1_LOG_SCALE_EN		BIT(5)

#define LP503X_LED_CONFIG0		0x2
#define   CONFIG0_LED0_BANK_EN		BIT(0)
#define   CONFIG0_LED1_BANK_EN		BIT(1)
#define   CONFIG0_LED2_BANK_EN		BIT(2)
#define   CONFIG0_LED3_BANK_EN		BIT(3)
#define   CONFIG0_LED4_BANK_EN		BIT(4)
#define   CONFIG0_LED5_BANK_EN		BIT(5)
#define   CONFIG0_LED6_BANK_EN		BIT(6)
#define   CONFIG0_LED7_BANK_EN		BIT(7)

#define LP503X_LED_CONFIG1		0x3
#define   CONFIG1_LED8_BANK_EN		BIT(0)
#define   CONFIG1_LED9_BANK_EN		BIT(1)
#define   CONFIG1_LED10_BANK_EN		BIT(2)
#define   CONFIG1_LED11_BANK_EN		BIT(3)

#define LP503X_BANK_BRIGHTNESS		0x4
#define LP503X_BANK_A_COLOR		0x5
#define LP503X_BANK_B_COLOR		0x6
#define LP503X_BANK_C_COLOR		0x7

#define LP503X_LED_BRIGHTNESS_BASE	0x8
#define LP503X_OUT_COLOR_BASE		0x14

/* Expose channels starting from the bank registers. */
#define LP503X_CHANNEL_BASE		LP503X_BANK_BRIGHTNESS

struct lp503x_config {
	struct i2c_dt_spec bus;
	uint8_t num_leds;
	bool log_scale_en;
	bool max_curr_opt;
	const struct led_info *leds_info;
};

struct lp503x_data {
	uint8_t *chan_buf;
};

static const struct led_info *
lp503x_led_to_info(const struct lp503x_config *config, uint32_t led)
{
	int i;

	for (i = 0; i < config->num_leds; i++) {
		if (config->leds_info[i].index == led) {
			return &config->leds_info[i];
		}
	}
	return NULL;
}

static int lp503x_get_info(const struct device *dev, uint32_t led,
			   const struct led_info **info)
{
	const struct lp503x_config *config = dev->config;
	const struct led_info *led_info = lp503x_led_to_info(config, led);

	if (!led_info) {
		return -EINVAL;
	}

	*info = led_info;

	return 0;
}

static int lp503x_set_brightness(const struct device *dev,
				 uint32_t led, uint8_t value)
{
	const struct lp503x_config *config = dev->config;
	const struct led_info *led_info = lp503x_led_to_info(config, led);
	uint8_t buf[2];

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

	buf[0] = LP503X_LED_BRIGHTNESS_BASE + led_info->index;
	buf[1] = (value * 0xff) / 100;

	return i2c_write_dt(&config->bus, buf, sizeof(buf));
}

static int lp503x_on(const struct device *dev, uint32_t led)
{
	return lp503x_set_brightness(dev, led, 100);
}

static int lp503x_off(const struct device *dev, uint32_t led)
{
	return lp503x_set_brightness(dev, led, 0);
}

static int lp503x_set_color(const struct device *dev, uint32_t led,
			    uint8_t num_colors, const uint8_t *color)
{
	const struct lp503x_config *config = dev->config;
	const struct led_info *led_info = lp503x_led_to_info(config, led);
	uint8_t buf[4];

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

	buf[0] = LP503X_OUT_COLOR_BASE + 3 * led_info->index;
	buf[1] = color[0];
	buf[2] = color[1];
	buf[3] = color[2];

	return i2c_write_dt(&config->bus, buf, sizeof(buf));
}

static int lp503x_write_channels(const struct device *dev,
				 uint32_t start_channel,
				 uint32_t num_channels, const uint8_t *buf)
{
	const struct lp503x_config *config = dev->config;
	struct lp503x_data *data = dev->data;

	if (start_channel >= LP503X_NUM_CHANNELS ||
	    start_channel + num_channels > LP503X_NUM_CHANNELS) {
		return -EINVAL;
	}

	/*
	 * Unfortunately this controller don't support commands split into
	 * two I2C messages.
	 */
	data->chan_buf[0] = LP503X_CHANNEL_BASE + start_channel;
	memcpy(data->chan_buf + 1, buf, num_channels);

	return i2c_write_dt(&config->bus, data->chan_buf, num_channels + 1);
}

static int lp503x_init(const struct device *dev)
{
	const struct lp503x_config *config = dev->config;
	uint8_t buf[3];
	int err;

	if (!device_is_ready(config->bus.bus)) {
		LOG_ERR("I2C device not ready");
		return -ENODEV;
	}
	if (config->num_leds > LP503X_MAX_LEDS) {
		LOG_ERR("%s: invalid number of LEDs %d (max %d)",
			dev->name, config->num_leds, LP503X_MAX_LEDS);
		return -EINVAL;
	}

	/*
	 * Since the status of the LP503x controller is unknown when entering
	 * 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] = LP503X_LED_CONFIG0;
	buf[1] = 0;
	buf[2] = 0;
	err = i2c_write_dt(&config->bus, buf, 3);
	if (err < 0) {
		return err;
	}

	/* Enable LED controller. */
	buf[0] = LP503X_DEVICE_CONFIG0;
	buf[1] = CONFIG0_CHIP_EN;
	err = i2c_write_dt(&config->bus, buf, 2);
	if (err < 0) {
		return err;
	}

	/* Apply configuration. */
	buf[0] = LP503X_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 lp503x_led_api = {
	.on		= lp503x_on,
	.off		= lp503x_off,
	.get_info	= lp503x_get_info,
	.set_brightness	= lp503x_set_brightness,
	.set_color	= lp503x_set_color,
	.write_channels	= lp503x_write_channels,
};

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

#define LED_INFO(led_node_id)					\
{								\
	.label		= DT_LABEL(led_node_id),		\
	.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 LP503x_DEVICE(id)					\
								\
DT_INST_FOREACH_CHILD(id, COLOR_MAPPING)			\
								\
const struct led_info lp503x_leds_##id[] = {			\
	DT_INST_FOREACH_CHILD(id, LED_INFO)			\
};								\
								\
static uint8_t lp503x_chan_buf_##id[LP503X_NUM_CHANNELS + 1];	\
								\
static const struct lp503x_config lp503x_config_##id = {	\
	.bus		= I2C_DT_SPEC_INST_GET(id),		\
	.num_leds	= ARRAY_SIZE(lp503x_leds_##id),		\
	.max_curr_opt	= DT_INST_PROP(id, max_curr_opt),	\
	.log_scale_en	= DT_INST_PROP(id, log_scale_en),	\
	.leds_info	= lp503x_leds_##id,			\
};								\
								\
static struct lp503x_data lp503x_data_##id = {			\
	.chan_buf	= lp503x_chan_buf_##id,			\
};								\
								\
DEVICE_DT_INST_DEFINE(id,					\
		    &lp503x_init,				\
		    NULL,					\
		    &lp503x_data_##id,				\
		    &lp503x_config_##id,			\
		    POST_KERNEL, CONFIG_LED_INIT_PRIORITY,	\
		    &lp503x_led_api);

DT_INST_FOREACH_STATUS_OKAY(LP503x_DEVICE)
