/*
 * Copyright (c) 2019 Henrik Brix Andersen <henrik@brixandersen.dk>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT holtek_ht16k33

/**
 * @file
 * @brief LED driver for the HT16K33 I2C LED driver with keyscan
 */

#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/led.h>
#include <zephyr/drivers/led/ht16k33.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(ht16k33, CONFIG_LED_LOG_LEVEL);

#include "led_context.h"

/* HT16K33 commands and options */
#define HT16K33_CMD_DISP_DATA_ADDR 0x00

#define HT16K33_CMD_SYSTEM_SETUP   0x20
#define HT16K33_OPT_S              BIT(0)

#define HT16K33_CMD_KEY_DATA_ADDR  0x40

#define HT16K33_CMD_INT_FLAG_ADDR  0x60

#define HT16K33_CMD_DISP_SETUP     0x80
#define HT16K33_OPT_D              BIT(0)
#define HT16K33_OPT_B0             BIT(1)
#define HT16K33_OPT_B1             BIT(2)
#define HT16K33_OPT_BLINK_OFF      0
#define HT16K33_OPT_BLINK_2HZ      HT16K33_OPT_B0
#define HT16K33_OPT_BLINK_1HZ      HT16K33_OPT_B1
#define HT16K33_OPT_BLINK_05HZ     (HT16K33_OPT_B1 | HT16K33_OPT_B0)

#define HT16K33_CMD_ROW_INT_SET    0xa0
#define HT16K33_OPT_ROW_INT        BIT(0)
#define HT16K33_OPT_ACT            BIT(1)
#define HT16K33_OPT_ROW            0
#define HT16K33_OPT_INT_LOW        HT16K33_OPT_ROW_INT
#define HT16K33_OPT_INT_HIGH       (HT16K33_OPT_ACT | HT16K33_OPT_ROW_INT)

#define HT16K33_CMD_DIMMING_SET    0xe0

/* HT16K33 size definitions */
#define HT16K33_DISP_ROWS          16
#define HT16K33_DISP_COLS          8
#define HT16K33_DISP_DATA_SIZE     HT16K33_DISP_ROWS
#define HT16K33_DISP_SEGMENTS      (HT16K33_DISP_ROWS * HT16K33_DISP_COLS)
#define HT16K33_DIMMING_LEVELS     16
#define HT16K33_KEYSCAN_ROWS       3
#define HT16K33_KEYSCAN_COLS       13
#define HT16K33_KEYSCAN_DATA_SIZE  6

struct ht16k33_cfg {
	struct i2c_dt_spec i2c;
	bool irq_enabled;
#ifdef CONFIG_HT16K33_KEYSCAN
	struct gpio_dt_spec irq;
#endif /* CONFIG_HT16K33_KEYSCAN */
};

struct ht16k33_data {
	const struct device *dev;
	struct led_data dev_data;
	 /* Shadow buffer for the display data RAM */
	uint8_t buffer[HT16K33_DISP_DATA_SIZE];
#ifdef CONFIG_HT16K33_KEYSCAN
	struct k_mutex lock;
	const struct device *child;
	kscan_callback_t kscan_cb;
	struct gpio_callback irq_cb;
	struct k_thread irq_thread;
	struct k_sem irq_sem;
	struct k_timer timer;
	uint16_t key_state[HT16K33_KEYSCAN_ROWS];

	K_KERNEL_STACK_MEMBER(irq_thread_stack,
			      CONFIG_HT16K33_KEYSCAN_IRQ_THREAD_STACK_SIZE);
#endif /* CONFIG_HT16K33_KEYSCAN */
};

static int ht16k33_led_blink(const struct device *dev, uint32_t led,
			     uint32_t delay_on, uint32_t delay_off)
{
	/* The HT16K33 blinks all LEDs at the same frequency */
	ARG_UNUSED(led);

	const struct ht16k33_cfg *config = dev->config;
	struct ht16k33_data *data = dev->data;
	struct led_data *dev_data = &data->dev_data;
	uint32_t period;
	uint8_t cmd;

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

	cmd = HT16K33_CMD_DISP_SETUP | HT16K33_OPT_D;
	if (delay_off == 0) {
		cmd |= HT16K33_OPT_BLINK_OFF;
	} else if (period > 1500)  {
		cmd |= HT16K33_OPT_BLINK_05HZ;
	} else if (period > 750)  {
		cmd |= HT16K33_OPT_BLINK_1HZ;
	} else {
		cmd |= HT16K33_OPT_BLINK_2HZ;
	}

	if (i2c_write_dt(&config->i2c, &cmd, sizeof(cmd))) {
		LOG_ERR("Setting HT16K33 blink frequency failed");
		return -EIO;
	}

	return 0;
}

static int ht16k33_led_set_brightness(const struct device *dev, uint32_t led,
				      uint8_t value)
{
	ARG_UNUSED(led);

	const struct ht16k33_cfg *config = dev->config;
	struct ht16k33_data *data = dev->data;
	struct led_data *dev_data = &data->dev_data;
	uint8_t dim;
	uint8_t cmd;

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

	dim = (value * (HT16K33_DIMMING_LEVELS - 1)) / dev_data->max_brightness;
	cmd = HT16K33_CMD_DIMMING_SET | dim;

	if (i2c_write_dt(&config->i2c, &cmd, sizeof(cmd))) {
		LOG_ERR("Setting HT16K33 brightness failed");
		return -EIO;
	}

	return 0;
}

static int ht16k33_led_set_state(const struct device *dev, uint32_t led,
				 bool on)
{
	const struct ht16k33_cfg *config = dev->config;
	struct ht16k33_data *data = dev->data;
	uint8_t cmd[2];
	uint8_t addr;
	uint8_t bit;

	if (led >= HT16K33_DISP_SEGMENTS) {
		return -EINVAL;
	}

	addr = led / HT16K33_DISP_COLS;
	bit = led % HT16K33_DISP_COLS;

	cmd[0] = HT16K33_CMD_DISP_DATA_ADDR | addr;
	if (on) {
		cmd[1] = data->buffer[addr] | BIT(bit);
	} else {
		cmd[1] = data->buffer[addr] & ~BIT(bit);
	}

	if (data->buffer[addr] == cmd[1]) {
		return 0;
	}

	if (i2c_write_dt(&config->i2c, cmd, sizeof(cmd))) {
		LOG_ERR("Setting HT16K33 LED %s failed", on ? "on" : "off");
		return -EIO;
	}

	data->buffer[addr] = cmd[1];

	return 0;
}

static int ht16k33_led_on(const struct device *dev, uint32_t led)
{
	return ht16k33_led_set_state(dev, led, true);
}

static int ht16k33_led_off(const struct device *dev, uint32_t led)
{
	return ht16k33_led_set_state(dev, led, false);
}

#ifdef CONFIG_HT16K33_KEYSCAN
static bool ht16k33_process_keyscan_data(const struct device *dev)
{
	const struct ht16k33_cfg *config = dev->config;
	struct ht16k33_data *data = dev->data;
	uint8_t keys[HT16K33_KEYSCAN_DATA_SIZE];
	bool pressed = false;
	uint16_t state;
	uint16_t changed;
	int row;
	int col;
	int err;

	err = i2c_burst_read_dt(&config->i2c, HT16K33_CMD_KEY_DATA_ADDR, keys, sizeof(keys));
	if (err) {
		LOG_WRN("Failed to to read HT16K33 key data (err %d)", err);
		/* Reprocess */
		return true;
	}

	k_mutex_lock(&data->lock, K_FOREVER);

	for (row = 0; row < HT16K33_KEYSCAN_ROWS; row++) {
		state = sys_get_le16(&keys[row * 2]);
		changed = data->key_state[row] ^ state;
		data->key_state[row] = state;

		if (state) {
			pressed = true;
		}

		if (data->kscan_cb == NULL) {
			continue;
		}

		for (col = 0; col < HT16K33_KEYSCAN_COLS; col++) {
			if (changed & BIT(col)) {
				data->kscan_cb(data->child, row, col,
					state & BIT(col));
			}
		}
	}

	k_mutex_unlock(&data->lock);

	return pressed;
}

static void ht16k33_irq_thread(struct ht16k33_data *data)
{
	bool pressed;

	while (true) {
		k_sem_take(&data->irq_sem, K_FOREVER);

		do {
			k_sem_reset(&data->irq_sem);
			pressed = ht16k33_process_keyscan_data(data->dev);
			k_msleep(CONFIG_HT16K33_KEYSCAN_DEBOUNCE_MSEC);
		} while (pressed);
	}
}

static void ht16k33_irq_callback(const struct device *gpiob,
				 struct gpio_callback *cb, uint32_t pins)
{
	struct ht16k33_data *data;

	ARG_UNUSED(gpiob);
	ARG_UNUSED(pins);

	data = CONTAINER_OF(cb, struct ht16k33_data, irq_cb);
	k_sem_give(&data->irq_sem);
}

static void ht16k33_timer_callback(struct k_timer *timer)
{
	struct ht16k33_data *data;

	data = CONTAINER_OF(timer, struct ht16k33_data, timer);
	k_sem_give(&data->irq_sem);
}

int ht16k33_register_keyscan_callback(const struct device *parent,
				      const struct device *child,
				      kscan_callback_t callback)
{
	struct ht16k33_data *data = parent->data;

	k_mutex_lock(&data->lock, K_FOREVER);
	data->child = child;
	data->kscan_cb = callback;
	k_mutex_unlock(&data->lock);

	return 0;
}
#endif /* CONFIG_HT16K33_KEYSCAN */

static int ht16k33_init(const struct device *dev)
{
	const struct ht16k33_cfg *config = dev->config;
	struct ht16k33_data *data = dev->data;
	struct led_data *dev_data = &data->dev_data;
	uint8_t cmd[1 + HT16K33_DISP_DATA_SIZE]; /* 1 byte command + data */
	int err;

	data->dev = dev;

	if (!device_is_ready(config->i2c.bus)) {
		LOG_ERR("I2C bus device not ready");
		return -EINVAL;
	}

	memset(&data->buffer, 0, sizeof(data->buffer));

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

	/* System oscillator on */
	cmd[0] = HT16K33_CMD_SYSTEM_SETUP | HT16K33_OPT_S;
	err = i2c_write_dt(&config->i2c, cmd, 1);
	if (err) {
		LOG_ERR("Enabling HT16K33 system oscillator failed (err %d)",
			err);
		return -EIO;
	}

	/* Clear display RAM */
	memset(cmd, 0, sizeof(cmd));
	cmd[0] = HT16K33_CMD_DISP_DATA_ADDR;
	err = i2c_write_dt(&config->i2c, cmd, sizeof(cmd));
	if (err) {
		LOG_ERR("Clearing HT16K33 display RAM failed (err %d)", err);
		return -EIO;
	}

	/* Full brightness */
	cmd[0] = HT16K33_CMD_DIMMING_SET | 0x0f;
	err = i2c_write_dt(&config->i2c, cmd, 1);
	if (err) {
		LOG_ERR("Setting HT16K33 brightness failed (err %d)", err);
		return -EIO;
	}

	/* Display on, blinking off */
	cmd[0] = HT16K33_CMD_DISP_SETUP | HT16K33_OPT_D | HT16K33_OPT_BLINK_OFF;
	err = i2c_write_dt(&config->i2c, cmd, 1);
	if (err) {
		LOG_ERR("Enabling HT16K33 display failed (err %d)", err);
		return -EIO;
	}

#ifdef CONFIG_HT16K33_KEYSCAN
	k_mutex_init(&data->lock);
	k_sem_init(&data->irq_sem, 0, 1);

	/* Configure interrupt */
	if (config->irq_enabled) {
		uint8_t keys[HT16K33_KEYSCAN_DATA_SIZE];

		if (!device_is_ready(config->irq.port)) {
			LOG_ERR("IRQ device not ready");
			return -EINVAL;
		}

		err = gpio_pin_configure_dt(&config->irq, GPIO_INPUT);
		if (err) {
			LOG_ERR("Failed to configure IRQ pin (err %d)", err);
			return -EINVAL;
		}

		gpio_init_callback(&data->irq_cb, &ht16k33_irq_callback,
				   BIT(config->irq.pin));

		err = gpio_add_callback(config->irq.port, &data->irq_cb);
		if (err) {
			LOG_ERR("Failed to add IRQ callback (err %d)", err);
			return -EINVAL;
		}

		/* Enable interrupt pin */
		cmd[0] = HT16K33_CMD_ROW_INT_SET | HT16K33_OPT_INT_LOW;
		if (i2c_write_dt(&config->i2c, cmd, 1)) {
			LOG_ERR("Enabling HT16K33 IRQ output failed");
			return -EIO;
		}

		/* Flush key data before enabling interrupt */
		err = i2c_burst_read_dt(&config->i2c, HT16K33_CMD_KEY_DATA_ADDR, keys,
					sizeof(keys));
		if (err) {
			LOG_ERR("Failed to to read HT16K33 key data");
			return -EIO;
		}

		err = gpio_pin_interrupt_configure_dt(&config->irq,
						      GPIO_INT_EDGE_FALLING);
		if (err) {
			LOG_ERR("Failed to configure IRQ pin flags (err %d)",
				err);
			return -EINVAL;
		}
	} else {
		/* No interrupt pin, enable ROW15 */
		cmd[0] = HT16K33_CMD_ROW_INT_SET | HT16K33_OPT_ROW;
		if (i2c_write_dt(&config->i2c, cmd, 1)) {
			LOG_ERR("Enabling HT16K33 ROW15 output failed");
			return -EIO;
		}

		/* Setup timer for polling key data */
		k_timer_init(&data->timer, ht16k33_timer_callback, NULL);
		k_timer_start(&data->timer, K_NO_WAIT,
			      K_MSEC(CONFIG_HT16K33_KEYSCAN_POLL_MSEC));
	}

	k_thread_create(&data->irq_thread, data->irq_thread_stack,
			CONFIG_HT16K33_KEYSCAN_IRQ_THREAD_STACK_SIZE,
			(k_thread_entry_t)ht16k33_irq_thread, data, NULL, NULL,
			K_PRIO_COOP(CONFIG_HT16K33_KEYSCAN_IRQ_THREAD_PRIO),
			0, K_NO_WAIT);
#endif /* CONFIG_HT16K33_KEYSCAN */

	return 0;
}

static const struct led_driver_api ht16k33_leds_api = {
	.blink = ht16k33_led_blink,
	.set_brightness = ht16k33_led_set_brightness,
	.on = ht16k33_led_on,
	.off = ht16k33_led_off,
};

#define HT16K33_DEVICE(id)						\
	static const struct ht16k33_cfg ht16k33_##id##_cfg = {		\
		.i2c = I2C_DT_SPEC_INST_GET(id),			\
		.irq_enabled  = false,					\
	};								\
									\
	static struct ht16k33_data ht16k33_##id##_data;			\
									\
	DEVICE_DT_INST_DEFINE(id, &ht16k33_init, NULL,			\
			    &ht16k33_##id##_data,			\
			    &ht16k33_##id##_cfg, POST_KERNEL,		\
			    CONFIG_LED_INIT_PRIORITY, &ht16k33_leds_api)

#ifdef CONFIG_HT16K33_KEYSCAN
#define HT16K33_DEVICE_WITH_IRQ(id)					\
	static const struct ht16k33_cfg ht16k33_##id##_cfg = {		\
		.i2c = I2C_DT_SPEC_INST_GET(id),			\
		.irq_enabled  = true,					\
		.irq          =	GPIO_DT_SPEC_INST_GET(id, irq_gpios),	\
	};								\
									\
	static struct ht16k33_data ht16k33_##id##_data;			\
									\
	DEVICE_DT_INST_DEFINE(id, &ht16k33_init, NULL,			\
			    &ht16k33_##id##_data,			\
			    &ht16k33_##id##_cfg, POST_KERNEL,		\
			    CONFIG_LED_INIT_PRIORITY, &ht16k33_leds_api)
#else /* ! CONFIG_HT16K33_KEYSCAN */
#define HT16K33_DEVICE_WITH_IRQ(id) HT16K33_DEVICE(id)
#endif /* ! CONFIG_HT16K33_KEYSCAN */

#define HT16K33_INSTANTIATE(id)					\
	COND_CODE_1(DT_INST_NODE_HAS_PROP(id, irq_gpios),	\
		    (HT16K33_DEVICE_WITH_IRQ(id)),		\
		    (HT16K33_DEVICE(id)));

DT_INST_FOREACH_STATUS_OKAY(HT16K33_INSTANTIATE)
