/*
 * Copyright (c) 2018 Linaro Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief LP3943 LED driver
 *
 * Limitations:
 * - Blink period and brightness value are controlled by two sets of PSCx/PWMx
 *   registers. This driver partitions the available LEDs into two groups as
 *   0 to 7 and 8 to 15 and assigns PSC0/PWM0 to LEDs from 0 to 7 and PSC1/PWM1
 *   to LEDs from 8 to 15. So, it is not possible to set unique blink period
 *   and brightness value for LEDs in a group, changing either of these
 *   values for a LED will affect other LEDs also.
 */

#include <drivers/i2c.h>
#include <drivers/led.h>
#include <sys/util.h>
#include <zephyr.h>

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

#ifdef CONFIG_HAS_DTS_I2C
#define CONFIG_LP3943_DEV_NAME			DT_INST_0_TI_LP3943_LABEL
#define CONFIG_LP3943_I2C_ADDRESS		DT_INST_0_TI_LP3943_BASE_ADDRESS
#define CONFIG_LP3943_I2C_MASTER_DEV_NAME	DT_INST_0_TI_LP3943_BUS_NAME
#endif

#include "led_context.h"

/* LP3943 Registers */
#define LP3943_INPUT_1 0x00
#define LP3943_INPUT_2 0x01
#define LP3943_PSC0 0x02
#define LP3943_PWM0 0x03
#define LP3943_PSC1 0x04
#define LP3943_PWM1 0x05
#define LP3943_LS0 0x06
#define LP3943_LS1 0x07
#define LP3943_LS2 0x08
#define LP3943_LS3 0x09

#define LP3943_MASK 0x03

enum lp3943_modes {
	LP3943_OFF,
	LP3943_ON,
	LP3943_DIM0,
	LP3943_DIM1,
};

struct lp3943_data {
	struct device *i2c;
	struct led_data dev_data;
};

static int lp3943_get_led_reg(u32_t *led, u8_t *reg)
{
	switch (*led) {
	case 0:
	case 1:
	case 2:
		/* Fall through */
	case 3:
		*reg = LP3943_LS0;
		break;
	case 4:
	case 5:
	case 6:
		/* Fall through */
	case 7:
		*reg = LP3943_LS1;
		*led -= 4U;
		break;
	case 8:
	case 9:
	case 10:
		/* Fall through */
	case 11:
		*reg = LP3943_LS2;
		*led -= 8U;
		break;
	case 12:
	case 13:
	case 14:
		/* Fall through */
	case 15:
		*reg = LP3943_LS3;
		*led -= 12U;
		break;
	default:
		LOG_ERR("Invalid LED specified");
		return -EINVAL;
	}

	return 0;
}

static int lp3943_set_dim_states(struct lp3943_data *data, u32_t led, u8_t mode)
{
	int ret;
	u8_t reg;

	ret = lp3943_get_led_reg(&led, &reg);
	if (ret) {
		return ret;
	}

	/* Set DIMx states for the LEDs */
	if (i2c_reg_update_byte(data->i2c, CONFIG_LP3943_I2C_ADDRESS, reg,
				LP3943_MASK << (led << 1),
				mode << (led << 1))) {
		LOG_ERR("LED reg update failed");
		return -EIO;
	}

	return 0;
}

static int lp3943_led_blink(struct device *dev, u32_t led,
			    u32_t delay_on, u32_t delay_off)
{
	struct lp3943_data *data = dev->driver_data;
	struct led_data *dev_data = &data->dev_data;
	int ret;
	u16_t period;
	u8_t reg, val, mode;

	period = delay_on + delay_off;

	if (period < dev_data->min_period || period > dev_data->max_period) {
		return -EINVAL;
	}

	/* Use DIM0 for LEDs 0 to 7 and DIM1 for LEDs 8 to 15 */
	if (led < 8) {
		mode = LP3943_DIM0;
	} else {
		mode = LP3943_DIM1;
	}

	if (mode == LP3943_DIM0) {
		reg = LP3943_PSC0;
	} else {
		reg = LP3943_PSC1;
	}

	val = (period * 255U) / dev_data->max_period;
	if (i2c_reg_write_byte(data->i2c, CONFIG_LP3943_I2C_ADDRESS,
			       reg, val)) {
		LOG_ERR("LED write failed");
		return -EIO;
	}

	ret = lp3943_set_dim_states(data, led, mode);
	if (ret) {
		return ret;
	}

	return 0;
}

static int lp3943_led_set_brightness(struct device *dev, u32_t led,
				     u8_t value)
{
	struct lp3943_data *data = dev->driver_data;
	struct led_data *dev_data = &data->dev_data;
	int ret;
	u8_t reg, val, mode;

	if (value < dev_data->min_brightness ||
			value > dev_data->max_brightness) {
		return -EINVAL;
	}

	/* Use DIM0 for LEDs 0 to 7 and DIM1 for LEDs 8 to 15 */
	if (led < 8) {
		mode = LP3943_DIM0;
	} else {
		mode = LP3943_DIM1;
	}

	if (mode == LP3943_DIM0) {
		reg = LP3943_PWM0;
	} else {
		reg = LP3943_PWM1;
	}

	val = (value * 255U) / dev_data->max_brightness;
	if (i2c_reg_write_byte(data->i2c, CONFIG_LP3943_I2C_ADDRESS,
			       reg, val)) {
		LOG_ERR("LED write failed");
		return -EIO;
	}

	ret = lp3943_set_dim_states(data, led, mode);
	if (ret) {
		return ret;
	}

	return 0;
}

static inline int lp3943_led_on(struct device *dev, u32_t led)
{
	struct lp3943_data *data = dev->driver_data;
	int ret;
	u8_t reg, mode;

	ret = lp3943_get_led_reg(&led, &reg);
	if (ret) {
		return ret;
	}

	/* Set LED state to ON */
	mode = LP3943_ON;
	if (i2c_reg_update_byte(data->i2c, CONFIG_LP3943_I2C_ADDRESS, reg,
				LP3943_MASK << (led << 1),
				mode << (led << 1))) {
		LOG_ERR("LED reg update failed");
		return -EIO;
	}

	return 0;
}

static inline int lp3943_led_off(struct device *dev, u32_t led)
{
	struct lp3943_data *data = dev->driver_data;
	int ret;
	u8_t reg;

	ret = lp3943_get_led_reg(&led, &reg);
	if (ret) {
		return ret;
	}

	/* Set LED state to OFF */
	if (i2c_reg_update_byte(data->i2c, CONFIG_LP3943_I2C_ADDRESS, reg,
				LP3943_MASK << (led << 1), 0)) {
		LOG_ERR("LED reg update failed");
		return -EIO;
	}

	return 0;
}

static int lp3943_led_init(struct device *dev)
{
	struct lp3943_data *data = dev->driver_data;
	struct led_data *dev_data = &data->dev_data;

	data->i2c = device_get_binding(CONFIG_LP3943_I2C_MASTER_DEV_NAME);
	if (data->i2c == NULL) {
		LOG_DBG("Failed to get I2C device");
		return -EINVAL;
	}

	/* Hardware specific limits */
	dev_data->min_period = 0U;
	dev_data->max_period = 1600U;
	dev_data->min_brightness = 0U;
	dev_data->max_brightness = 100U;

	return 0;
}

static struct lp3943_data lp3943_led_data;

static const struct led_driver_api lp3943_led_api = {
	.blink = lp3943_led_blink,
	.set_brightness = lp3943_led_set_brightness,
	.on = lp3943_led_on,
	.off = lp3943_led_off,
};

DEVICE_AND_API_INIT(lp3943_led, CONFIG_LP3943_DEV_NAME,
		    &lp3943_led_init, &lp3943_led_data,
		    NULL, POST_KERNEL, CONFIG_LED_INIT_PRIORITY,
		    &lp3943_led_api);
