/*
 * Copyright (c) 2020 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <drivers/kscan.h>
#include <drivers/i2c.h>
#include <logging/log.h>

LOG_MODULE_REGISTER(ft5336, CONFIG_KSCAN_LOG_LEVEL);

#define FT5406_DATA_SIZE	0x20

enum ft5336_event {
	FT5336_EVENT_DOWN	= 0,
	FT5336_EVENT_UP		= 1,
	FT5336_EVENT_CONTACT	= 2,
	FT5336_EVENT_RESERVED	= 3,
};

struct ft5336_config {
	char *i2c_name;
	u8_t i2c_address;
};

struct ft5336_data {
	struct device *i2c;
	kscan_callback_t callback;
	struct k_work work;
	struct k_timer timer;
	struct device *dev;
};

static int ft5336_read(struct device *dev)
{
	const struct ft5336_config *config = dev->config->config_info;
	struct ft5336_data *data = dev->driver_data;
	u8_t buffer[FT5406_DATA_SIZE];
	u8_t event;
	u16_t row, column;
	bool pressed;

	if (i2c_burst_read(data->i2c, config->i2c_address, 1, buffer,
			   sizeof(buffer))) {
		LOG_ERR("Could not read point");
		return -EIO;
	}

	event = buffer[2] >> 6;
	pressed = (event == FT5336_EVENT_DOWN) ||
		  (event == FT5336_EVENT_CONTACT);

	row = ((buffer[2] & 0x0f) << 8) | buffer[3];
	column = ((buffer[4] & 0x0f) << 8) | buffer[5];

	data->callback(dev, row, column, pressed);

	return 0;
}

static void ft5336_timer_handler(struct k_timer *timer)
{
	struct ft5336_data *data =
		CONTAINER_OF(timer, struct ft5336_data, timer);

	k_work_submit(&data->work);
}

static void ft5336_work_handler(struct k_work *work)
{
	struct ft5336_data *data =
		CONTAINER_OF(work, struct ft5336_data, work);

	ft5336_read(data->dev);
}

static int ft5336_configure(struct device *dev, kscan_callback_t callback)
{
	struct ft5336_data *data = dev->driver_data;

	if (!callback) {
		return -EINVAL;
	}

	data->callback = callback;

	return 0;
}

static int ft5336_enable_callback(struct device *dev)
{
	struct ft5336_data *data = dev->driver_data;

	k_timer_start(&data->timer, K_MSEC(CONFIG_KSCAN_FT5336_PERIOD),
		      K_MSEC(CONFIG_KSCAN_FT5336_PERIOD));

	return 0;
}

static int ft5336_disable_callback(struct device *dev)
{
	struct ft5336_data *data = dev->driver_data;

	k_timer_stop(&data->timer);

	return 0;
}

static int ft5336_init(struct device *dev)
{
	const struct ft5336_config *config = dev->config->config_info;
	struct ft5336_data *data = dev->driver_data;

	data->i2c = device_get_binding(config->i2c_name);
	if (data->i2c == NULL) {
		LOG_ERR("Could not find I2C device");
		return -EINVAL;
	}

	if (i2c_reg_write_byte(data->i2c, config->i2c_address, 0, 0)) {
		LOG_ERR("Could not enable");
		return -EINVAL;
	}

	data->dev = dev;

	k_work_init(&data->work, ft5336_work_handler);
	k_timer_init(&data->timer, ft5336_timer_handler, NULL);

	return 0;
}


static const struct kscan_driver_api ft5336_driver_api = {
	.config = ft5336_configure,
	.enable_callback = ft5336_enable_callback,
	.disable_callback = ft5336_disable_callback,
};

static const struct ft5336_config ft5336_config = {
	.i2c_name = DT_INST_0_FOCALTECH_FT5336_BUS_NAME,
	.i2c_address = DT_INST_0_FOCALTECH_FT5336_BASE_ADDRESS,
};

static struct ft5336_data ft5336_data;

DEVICE_AND_API_INIT(ft5336, DT_INST_0_FOCALTECH_FT5336_LABEL, ft5336_init,
		    &ft5336_data, &ft5336_config,
		    POST_KERNEL, CONFIG_KSCAN_INIT_PRIORITY,
		    &ft5336_driver_api);
