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

#define DT_DRV_COMPAT ti_lp503x

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

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

#define LOG_LEVEL CONFIG_LED_LOG_LEVEL
#include <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 {
	char *i2c_bus_label;
	uint8_t i2c_addr;
	uint8_t num_leds;
	bool log_scale_en;
	bool max_curr_opt;
	const struct led_info *leds_info;
};

struct lp503x_data {
	const struct device *i2c;
	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;
	struct lp503x_data *data = dev->data;
	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(data->i2c, buf, sizeof(buf), config->i2c_addr);
}

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;
	struct lp503x_data *data = dev->data;
	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(data->i2c, buf, sizeof(buf), config->i2c_addr);
}

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(data->i2c, data->chan_buf,
			 num_channels + 1, config->i2c_addr);
}

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

	data->i2c = device_get_binding(config->i2c_bus_label);
	if (data->i2c == NULL) {
		LOG_ERR("%s: device %s not found",
			dev->name, config->i2c_bus_label);
		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(data->i2c, buf, 3, config->i2c_addr);
	if (err < 0) {
		return err;
	}

	/* Enable LED controller. */
	buf[0] = LP503X_DEVICE_CONFIG0;
	buf[1] = CONFIG0_CHIP_EN;
	err = i2c_write(data->i2c, buf, 2, config->i2c_addr);
	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(data->i2c, buf, 2, config->i2c_addr);
}

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 struct lp503x_config lp503x_config_##id = {		\
	.i2c_bus_label	= DT_INST_BUS_LABEL(id),		\
	.i2c_addr	= DT_INST_REG_ADDR(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)
