/*
 * 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 <drivers/gpio.h>
#include <drivers/i2c.h>
#include <kernel.h>
#include <drivers/led.h>
#include <sys/byteorder.h>
#include <zephyr.h>

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

#include <drivers/led/ht16k33.h>

#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 {
	char *i2c_dev_name;
	u16_t i2c_addr;
	bool irq_enabled;
#ifdef CONFIG_HT16K33_KEYSCAN
	char *irq_dev_name;
	u32_t irq_pin;
	int irq_flags;
#endif /* CONFIG_HT16K33_KEYSCAN */
};

struct ht16k33_data {
	struct device *i2c;
	struct led_data dev_data;
	 /* Shadow buffer for the display data RAM */
	u8_t buffer[HT16K33_DISP_DATA_SIZE];
#ifdef CONFIG_HT16K33_KEYSCAN
	struct k_mutex lock;
	struct device *children[HT16K33_KEYSCAN_ROWS];
	struct gpio_callback irq_cb;
	struct k_thread irq_thread;
	struct k_sem irq_sem;
	struct k_timer timer;
	u16_t key_state[HT16K33_KEYSCAN_ROWS];

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

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

	const struct ht16k33_cfg *config = dev->config_info;
	struct ht16k33_data *data = dev->driver_data;
	struct led_data *dev_data = &data->dev_data;
	u32_t period;
	u8_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(data->i2c, &cmd, 1, config->i2c_addr)) {
		LOG_ERR("Setting HT16K33 blink frequency failed");
		return -EIO;
	}

	return 0;
}

static int ht16k33_led_set_brightness(struct device *dev, u32_t led,
				      u8_t value)
{
	ARG_UNUSED(led);

	const struct ht16k33_cfg *config = dev->config_info;
	struct ht16k33_data *data = dev->driver_data;
	struct led_data *dev_data = &data->dev_data;
	u8_t dim;
	u8_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(data->i2c, &cmd, 1, config->i2c_addr)) {
		LOG_ERR("Setting HT16K33 brightness failed");
		return -EIO;
	}

	return 0;
}

static int ht16k33_led_set_state(struct device *dev, u32_t led, bool on)
{
	const struct ht16k33_cfg *config = dev->config_info;
	struct ht16k33_data *data = dev->driver_data;
	u8_t cmd[2];
	u8_t addr;
	u8_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(data->i2c, cmd, sizeof(cmd), config->i2c_addr)) {
		LOG_ERR("Setting HT16K33 LED %s failed", on ? "on" : "off");
		return -EIO;
	}

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

	return 0;
}

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

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

#ifdef CONFIG_HT16K33_KEYSCAN
u32_t ht16k33_get_pending_int(struct device *dev)
{
	const struct ht16k33_cfg *config = dev->config_info;
	struct ht16k33_data *data = dev->driver_data;
	u8_t cmd;
	u8_t flag;
	int err;

	cmd = HT16K33_CMD_INT_FLAG_ADDR;
	err = i2c_write_read(data->i2c, config->i2c_addr, &cmd, sizeof(cmd),
			     &flag, sizeof(flag));
	if (err) {
		LOG_ERR("Failed to to read HT16K33 IRQ flag");
		return 0;
	}

	return (flag ? 1 : 0);
}

static bool ht16k33_process_keyscan_data(struct device *dev)
{
	const struct ht16k33_cfg *config = dev->config_info;
	struct ht16k33_data *data = dev->driver_data;
	u8_t keys[HT16K33_KEYSCAN_DATA_SIZE];
	bool pressed = false;
	u16_t row;
	u16_t new;
	int err;
	int i;

	err = i2c_burst_read(data->i2c, config->i2c_addr,
			     HT16K33_CMD_KEY_DATA_ADDR, keys,
			     sizeof(keys));
	if (err) {
		LOG_ERR("Failed to to read HT16K33 key data (err %d)", err);
		return false;
	}

	k_mutex_lock(&data->lock, K_FOREVER);
	for (i = 0; i < HT16K33_KEYSCAN_ROWS; i++) {
		row = sys_get_le16(&keys[i * 2]);
		if (row) {
			pressed = true;
			new = data->key_state[i] ^ row;
			new &= row;
			if (data->children[i] && new) {
				ht16k33_process_keyscan_row_data(
					data->children[i], new);
			}
		}
		data->key_state[i] = row;
	}
	k_mutex_unlock(&data->lock);

	return pressed;
}

static void ht16k33_irq_thread(struct device *dev)
{
	struct ht16k33_data *data = dev->driver_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(dev);
			k_msleep(CONFIG_HT16K33_KEYSCAN_DEBOUNCE_MSEC);
		} while (pressed);
	}
}

static void ht16k33_irq_callback(struct device *gpiob,
				 struct gpio_callback *cb, u32_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_device(struct device *parent,
					   struct device *child,
					   u8_t keyscan_idx)
{
	struct ht16k33_data *data = parent->driver_data;

	k_mutex_lock(&data->lock, K_FOREVER);

	if (data->children[keyscan_idx]) {
		k_mutex_unlock(&data->lock);
		LOG_ERR("HT16K33 keyscan device %d already registered",
			keyscan_idx);
		return -EINVAL;
	}

	data->children[keyscan_idx] = child;
	k_mutex_unlock(&data->lock);

	return 0;
}
#endif /* CONFIG_HT16K33_KEYSCAN */

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

	data->i2c = device_get_binding(config->i2c_dev_name);
	if (data->i2c == NULL) {
		LOG_ERR("Failed to get I2C device");
		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(data->i2c, cmd, 1, config->i2c_addr);
	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(data->i2c, cmd, sizeof(cmd), config->i2c_addr);
	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(data->i2c, cmd, 1, config->i2c_addr);
	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(data->i2c, cmd, 1, config->i2c_addr);
	if (err) {
		LOG_ERR("Enabling HT16K33 display failed (err %d)", err);
		return -EIO;
	}

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

	/* Configure interrupt */
	if (config->irq_enabled) {
		struct device *irq_dev;
		u8_t keys[HT16K33_KEYSCAN_DATA_SIZE];

		irq_dev = device_get_binding(config->irq_dev_name);
		if (!irq_dev) {
			LOG_ERR("IRQ device '%s' not found",
				config->irq_dev_name);
			return -EINVAL;
		}

		err = gpio_pin_configure(irq_dev, config->irq_pin,
					 GPIO_INPUT | config->irq_flags);
		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(irq_dev, &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(data->i2c, cmd, 1, config->i2c_addr)) {
			LOG_ERR("Enabling HT16K33 IRQ output failed");
			return -EIO;
		}

		/* Flush key data before enabling interrupt */
		err = i2c_burst_read(data->i2c, config->i2c_addr,
				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(irq_dev, config->irq_pin,
						   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(data->i2c, cmd, 1, config->i2c_addr)) {
			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, dev, 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_dev_name = DT_INST_BUS_LABEL(id),			\
		.i2c_addr     = DT_INST_REG_ADDR(id),			\
		.irq_enabled  = false,					\
	};								\
									\
	static struct ht16k33_data ht16k33_##id##_data;			\
									\
	DEVICE_AND_API_INIT(ht16k33_##id, DT_INST_LABEL(id),		\
			    &ht16k33_init, &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_dev_name = DT_INST_BUS_LABEL(id),			\
		.i2c_addr     = DT_INST_REG_ADDR(id),			\
		.irq_enabled  = true,					\
		.irq_dev_name =						\
		DT_INST_GPIO_LABEL(id, irq_gpios),			\
		.irq_pin      = DT_INST_GPIO_PIN(id, irq_gpios),	\
		.irq_flags    =						\
		DT_INST_GPIO_FLAGS(id, irq_gpios),			\
	};								\
									\
	static struct ht16k33_data ht16k33_##id##_data;			\
									\
	DEVICE_AND_API_INIT(ht16k33_##id, DT_INST_LABEL(id),		\
			    &ht16k33_init, &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)
