/*
 * Copyright (c) 2021 Qingsong Gou <gouqs@hotmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT hynitron_cst816s

#include <zephyr/sys/byteorder.h>
#include <zephyr/input/input.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(cst816s, CONFIG_INPUT_LOG_LEVEL);

#define CST816S_CHIP_ID 0xB4

#define CST816S_REG_DATA                0x00
#define CST816S_REG_GESTURE_ID          0x01
#define CST816S_REG_FINGER_NUM          0x02
#define CST816S_REG_XPOS_H              0x03
#define CST816S_REG_XPOS_L              0x04
#define CST816S_REG_YPOS_H              0x05
#define CST816S_REG_YPOS_L              0x06
#define CST816S_REG_BPC0H               0xB0
#define CST816S_REG_BPC0L               0xB1
#define CST816S_REG_BPC1H               0xB2
#define CST816S_REG_BPC1L               0xB3
#define CST816S_REG_POWER_MODE          0xA5
#define CST816S_REG_CHIP_ID             0xA7
#define CST816S_REG_PROJ_ID             0xA8
#define CST816S_REG_FW_VERSION          0xA9
#define CST816S_REG_MOTION_MASK         0xEC
#define CST816S_REG_IRQ_PULSE_WIDTH     0xED
#define CST816S_REG_NOR_SCAN_PER        0xEE
#define CST816S_REG_MOTION_S1_ANGLE     0xEF
#define CST816S_REG_LP_SCAN_RAW1H       0xF0
#define CST816S_REG_LP_SCAN_RAW1L       0xF1
#define CST816S_REG_LP_SCAN_RAW2H       0xF2
#define CST816S_REG_LP_SCAN_RAW2L       0xF3
#define CST816S_REG_LP_AUTO_WAKEUP_TIME 0xF4
#define CST816S_REG_LP_SCAN_TH          0xF5
#define CST816S_REG_LP_SCAN_WIN         0xF6
#define CST816S_REG_LP_SCAN_FREQ        0xF7
#define CST816S_REG_LP_SCAN_I_DAC       0xF8
#define CST816S_REG_AUTOSLEEP_TIME      0xF9
#define CST816S_REG_IRQ_CTL             0xFA
#define CST816S_REG_DEBOUNCE_TIME       0xFB
#define CST816S_REG_LONG_PRESS_TIME     0xFC
#define CST816S_REG_IOCTL               0xFD
#define CST816S_REG_DIS_AUTO_SLEEP      0xFE

#define CST816S_MOTION_EN_CON_LR BIT(2)
#define CST816S_MOTION_EN_CON_UR BIT(1)
#define CST816S_MOTION_EN_DCLICK BIT(0)

#define CST816S_IRQ_EN_TEST   BIT(7)
#define CST816S_IRQ_EN_TOUCH  BIT(6)
#define CST816S_IRQ_EN_CHANGE BIT(5)
#define CST816S_IRQ_EN_MOTION BIT(4)
#define CST816S_IRQ_ONCE_WLP  BIT(0)

#define CST816S_IOCTL_SOFT_RTS BIT(2)
#define CST816S_IOCTL_IIC_OD   BIT(1)
#define CST816S_IOCTL_EN_1V8   BIT(0)

#define CST816S_POWER_MODE_SLEEP        (0x03)
#define CST816S_POWER_MODE_EXPERIMENTAL (0x05)

#define CST816S_EVENT_BITS_POS (0x06)

#define CST816S_RESET_DELAY (5)  /* in ms */
#define CST816S_WAIT_DELAY  (50) /* in ms */

#define EVENT_PRESS_DOWN 0x00U
#define EVENT_LIFT_UP    0x01U
#define EVENT_CONTACT    0x02U
#define EVENT_NONE       0x03U

/** cst816s configuration (DT). */
struct cst816s_config {
	struct i2c_dt_spec i2c;
	const struct gpio_dt_spec rst_gpio;
#ifdef CONFIG_INPUT_CST816S_INTERRUPT
	const struct gpio_dt_spec int_gpio;
#endif
};

/** cst816s data. */
struct cst816s_data {
	/** Device pointer. */
	const struct device *dev;
	/** Work queue (for deferred read). */
	struct k_work work;

#ifdef CONFIG_INPUT_CST816S_INTERRUPT
	/** Interrupt GPIO callback. */
	struct gpio_callback int_gpio_cb;
#else
	/** Timer (polling mode). */
	struct k_timer timer;
#endif
};

static int cst816s_process(const struct device *dev)
{
	const struct cst816s_config *cfg = dev->config;

	int r;
	uint8_t event;
	uint16_t row, col;
	bool pressed;
	uint16_t x;
	uint16_t y;

	r = i2c_burst_read_dt(&cfg->i2c, CST816S_REG_XPOS_H, (uint8_t *)&x, sizeof(x));
	if (r < 0) {
		LOG_ERR("Could not read x data");
		return r;
	}

	r = i2c_burst_read_dt(&cfg->i2c, CST816S_REG_YPOS_H, (uint8_t *)&y, sizeof(y));
	if (r < 0) {
		LOG_ERR("Could not read y data");
		return r;
	}
	col = sys_be16_to_cpu(x) & 0x0fff;
	row = sys_be16_to_cpu(y) & 0x0fff;

	event = (x & 0xff) >> CST816S_EVENT_BITS_POS;
	pressed = (event == EVENT_PRESS_DOWN) || (event == EVENT_CONTACT);

	LOG_DBG("event: %d, row: %d, col: %d", event, row, col);

	if (pressed) {
		input_report_abs(dev, INPUT_ABS_X, col, false, K_FOREVER);
		input_report_abs(dev, INPUT_ABS_Y, row, false, K_FOREVER);
		input_report_key(dev, INPUT_BTN_TOUCH, 1, true, K_FOREVER);
	} else {
		input_report_key(dev, INPUT_BTN_TOUCH, 0, true, K_FOREVER);
	}

	return r;
}

static void cst816s_work_handler(struct k_work *work)
{
	struct cst816s_data *data = CONTAINER_OF(work, struct cst816s_data, work);

	cst816s_process(data->dev);
}

#ifdef CONFIG_INPUT_CST816S_INTERRUPT
static void cst816s_isr_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
	struct cst816s_data *data = CONTAINER_OF(cb, struct cst816s_data, int_gpio_cb);

	k_work_submit(&data->work);
}
#else
static void cst816s_timer_handler(struct k_timer *timer)
{
	struct cst816s_data *data = CONTAINER_OF(timer, struct cst816s_data, timer);

	k_work_submit(&data->work);
}
#endif

static void cst816s_chip_reset(const struct device *dev)
{
	const struct cst816s_config *config = dev->config;
	int ret;

	if (gpio_is_ready_dt(&config->rst_gpio)) {
		ret = gpio_pin_configure_dt(&config->rst_gpio, GPIO_OUTPUT_ACTIVE);
		if (ret < 0) {
			LOG_ERR("Could not configure reset GPIO pin");
			return;
		}
		k_msleep(CST816S_RESET_DELAY);
		gpio_pin_set_dt(&config->rst_gpio, 0);
		k_msleep(CST816S_WAIT_DELAY);
	}
}

static int cst816s_chip_init(const struct device *dev)
{
	const struct cst816s_config *cfg = dev->config;
	int ret = 0;
	uint8_t chip_id = 0;

	cst816s_chip_reset(dev);

	if (!device_is_ready(cfg->i2c.bus)) {
		LOG_ERR("I2C bus %s not ready", cfg->i2c.bus->name);
		return -ENODEV;
	}
	ret = i2c_reg_read_byte_dt(&cfg->i2c, CST816S_REG_CHIP_ID, &chip_id);
	if (ret < 0) {
		LOG_ERR("failed reading chip id");
		return ret;
	}

	if (chip_id != CST816S_CHIP_ID) {
		LOG_ERR("CST816S wrong chip id: returned 0x%x", chip_id);
		return -ENODEV;
	}

	ret = i2c_reg_update_byte_dt(&cfg->i2c, CST816S_REG_IRQ_CTL,
				     CST816S_IRQ_EN_TOUCH | CST816S_IRQ_EN_CHANGE,
				     CST816S_IRQ_EN_TOUCH | CST816S_IRQ_EN_CHANGE);
	if (ret < 0) {
		LOG_ERR("Could not enable irq");
		return ret;
	}
	return ret;
}

static int cst816s_init(const struct device *dev)
{
	struct cst816s_data *data = dev->data;

	data->dev = dev;
	k_work_init(&data->work, cst816s_work_handler);

#ifdef CONFIG_INPUT_CST816S_INTERRUPT
	const struct cst816s_config *config = dev->config;
	int ret;

	if (!gpio_is_ready_dt(&config->int_gpio)) {
		LOG_ERR("GPIO port %s not ready", config->int_gpio.port->name);
		return -ENODEV;
	}

	ret = gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT);
	if (ret < 0) {
		LOG_ERR("Could not configure interrupt GPIO pin");
		return ret;
	}

	ret = gpio_pin_interrupt_configure_dt(&config->int_gpio, GPIO_INT_EDGE_TO_ACTIVE);
	if (ret < 0) {
		LOG_ERR("Could not configure interrupt GPIO interrupt.");
		return ret;
	}

	gpio_init_callback(&data->int_gpio_cb, cst816s_isr_handler, BIT(config->int_gpio.pin));

	ret = gpio_add_callback(config->int_gpio.port, &data->int_gpio_cb);
	if (ret < 0) {
		LOG_ERR("Could not set gpio callback");
		return ret;
	}
#else
	k_timer_init(&data->timer, cst816s_timer_handler, NULL);
	k_timer_start(&data->timer, K_MSEC(CONFIG_INPUT_CST816S_PERIOD),
		      K_MSEC(CONFIG_INPUT_CST816S_PERIOD));
#endif

	return cst816s_chip_init(dev);
}

#define CST816S_DEFINE(index)                                                                      \
	static const struct cst816s_config cst816s_config_##index = {                              \
		.i2c = I2C_DT_SPEC_INST_GET(index),                                                \
		COND_CODE_1(CONFIG_INPUT_CST816S_INTERRUPT,                                        \
			    (.int_gpio = GPIO_DT_SPEC_INST_GET(index, irq_gpios),), ())           \
			.rst_gpio = GPIO_DT_SPEC_INST_GET_OR(index, rst_gpios, {}),                \
	};                                                                                         \
	static struct cst816s_data cst816s_data_##index;                                           \
	DEVICE_DT_INST_DEFINE(index, cst816s_init, NULL, &cst816s_data_##index,                    \
			      &cst816s_config_##index, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY,    \
			      NULL);

DT_INST_FOREACH_STATUS_OKAY(CST816S_DEFINE)
