/*
 * Copyright 2023 Google LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#define DT_DRV_COMPAT zephyr_kscan_input

#include <zephyr/drivers/kscan.h>
#include <zephyr/input/input.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(kscan_input, CONFIG_KSCAN_LOG_LEVEL);

struct kscan_input_config {
	const struct device *input_dev;
};

struct kscan_input_data {
	bool enabled;
	kscan_callback_t callback;
	int row;
	int col;
	bool pressed;
};

static void kscan_input_cb(const struct device *dev, struct input_event *evt)
{
	struct kscan_input_data *data = dev->data;

	switch (evt->code) {
	case INPUT_ABS_X:
		data->col = evt->value;
		break;
	case INPUT_ABS_Y:
		data->row = evt->value;
		break;
	case INPUT_BTN_TOUCH:
		data->pressed = evt->value;
		break;
	}

	if (evt->sync) {
		LOG_DBG("input event: %3d %3d %d",
			data->row, data->col, data->pressed);
		if (data->callback) {
			data->callback(dev, data->row, data->col, data->pressed);
		}
	}
}

static int kscan_input_configure(const struct device *dev,
				      kscan_callback_t callback)
{
	struct kscan_input_data *data = dev->data;

	if (!callback) {
		LOG_ERR("Invalid callback (NULL)");
		return -EINVAL;
	}

	data->callback = callback;

	return 0;
}

static int kscan_input_enable_callback(const struct device *dev)
{
	struct kscan_input_data *data = dev->data;

	data->enabled = true;

	return 0;
}

static int kscan_input_disable_callback(const struct device *dev)
{
	struct kscan_input_data *data = dev->data;

	data->enabled = false;

	return 0;
}

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

	if (!device_is_ready(cfg->input_dev)) {
		LOG_ERR("Input device not ready");
		return -ENODEV;
	}

	return 0;
}

static const struct kscan_driver_api kscan_input_driver_api = {
	.config = kscan_input_configure,
	.enable_callback = kscan_input_enable_callback,
	.disable_callback = kscan_input_disable_callback,
};

#define KSCAN_INPUT_INIT(index) \
	static void kscan_input_cb_##index(struct input_event *evt)            \
	{                                                                      \
		kscan_input_cb(DEVICE_DT_GET(DT_INST(index, DT_DRV_COMPAT)),   \
			       evt);                                           \
	}                                                                      \
	INPUT_LISTENER_CB_DEFINE(DEVICE_DT_GET(DT_INST_PARENT(index)),         \
				 kscan_input_cb_##index);                      \
	static const struct kscan_input_config kscan_input_config_##index = {  \
		.input_dev = DEVICE_DT_GET(DT_INST_PARENT(index)),             \
	};                                                                     \
	static struct kscan_input_data kscan_input_data_##index;               \
	DEVICE_DT_INST_DEFINE(index, kscan_input_init, NULL,                   \
			      &kscan_input_data_##index,                       \
			      &kscan_input_config_##index,                     \
			      POST_KERNEL, CONFIG_KSCAN_INIT_PRIORITY,         \
			      &kscan_input_driver_api);

DT_INST_FOREACH_STATUS_OKAY(KSCAN_INPUT_INIT)
