/*
 * 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

#define DEV_CFG(dev)	((const struct lp503x_config *) ((dev)->config))
#define DEV_DATA(dev)	((struct lp503x_data *) ((dev)->data))

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_CFG(dev);
	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_CFG(dev);
	struct lp503x_data *data = DEV_DATA(dev);
	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_CFG(dev);
	struct lp503x_data *data = DEV_DATA(dev);
	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_CFG(dev);
	struct lp503x_data *data = DEV_DATA(dev);

	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_CFG(dev);
	struct lp503x_data *data = DEV_DATA(dev);
	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_AND_API_INIT(lp503x_led_##id, DT_INST_LABEL(id),		\
		    &lp503x_init,				\
		    &lp503x_data_##id,				\
		    &lp503x_config_##id,			\
		    POST_KERNEL, CONFIG_LED_INIT_PRIORITY,	\
		    &lp503x_led_api);

DT_INST_FOREACH_STATUS_OKAY(LP503x_DEVICE)
