/*
 * Copyright 2019 Intel Corporation
 * Copyright 2022 Nuvoton Technology Corporation.
 * Copyright 2023 Google LLC
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/device.h>
#include <zephyr/input/input.h>
#include <zephyr/input/input_kbd_matrix.h>
#include <zephyr/kernel.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>

LOG_MODULE_REGISTER(input_kbd_matrix, CONFIG_INPUT_LOG_LEVEL);

void input_kbd_matrix_poll_start(const struct device *dev)
{
	struct input_kbd_matrix_common_data *data = dev->data;

	k_sem_give(&data->poll_lock);
}

static bool input_kbd_matrix_ghosting(const struct device *dev)
{
	const struct input_kbd_matrix_common_config *cfg = dev->config;
	const kbd_row_t *state = cfg->matrix_new_state;

	/*
	 * Matrix keyboard designs are suceptible to ghosting.
	 * An extra key appears to be pressed when 3 keys belonging to the same
	 * block are pressed. For example, in the following block:
	 *
	 * . . w . q .
	 * . . . . . .
	 * . . . . . .
	 * . . m . a .
	 *
	 * the key m would look as pressed if the user pressed keys w, q and a
	 * simultaneously. A block can also be formed, with not adjacent
	 * columns.
	 */
	for (int c = 0; c < cfg->col_size; c++) {
		if (!state[c]) {
			continue;
		}

		for (int c_next = c + 1; c_next < cfg->col_size; c_next++) {
			/*
			 * We AND the columns to detect a "block". This is an
			 * indication of ghosting, due to current flowing from
			 * a key which was never pressed. In our case, current
			 * flowing is a bit set to 1 as we flipped the bits
			 * when the matrix was scanned. Now we OR the colums
			 * using z&(z-1) which is non-zero only if z has more
			 * than one bit set.
			 */
			kbd_row_t common_row_bits = state[c] & state[c_next];

			if (common_row_bits & (common_row_bits - 1)) {
				return true;
			}
		}
	}

	return false;
}

static void input_kbd_matrix_drive_column(const struct device *dev, int col)
{
	const struct input_kbd_matrix_common_config *cfg = dev->config;
	const struct input_kbd_matrix_api *api = cfg->api;

	api->drive_column(dev, col);

#ifdef CONFIG_INPUT_KBD_DRIVE_COLUMN_HOOK
	input_kbd_matrix_drive_column_hook(dev, col);
#endif
}

static bool input_kbd_matrix_scan(const struct device *dev)
{
	const struct input_kbd_matrix_common_config *cfg = dev->config;
	const struct input_kbd_matrix_api *api = cfg->api;
	kbd_row_t row;
	kbd_row_t key_event = 0U;

	for (int col = 0; col < cfg->col_size; col++) {
		input_kbd_matrix_drive_column(dev, col);

		/* Allow the matrix to stabilize before reading it */
		k_busy_wait(cfg->settle_time_us);

		row = api->read_row(dev);

		if (cfg->actual_key_mask != NULL) {
			row &= cfg->actual_key_mask[col];
		}

		cfg->matrix_new_state[col] = row;
		key_event |= row;
	}

	input_kbd_matrix_drive_column(dev, INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE);

	return key_event != 0U;
}

static void input_kbd_matrix_update_state(const struct device *dev)
{
	const struct input_kbd_matrix_common_config *cfg = dev->config;
	struct input_kbd_matrix_common_data *data = dev->data;
	kbd_row_t *matrix_new_state = cfg->matrix_new_state;
	uint32_t cycles_now;
	kbd_row_t row_changed;
	kbd_row_t deb_col;

	cycles_now = k_cycle_get_32();

	data->scan_clk_cycle[data->scan_cycles_idx] = cycles_now;

	/*
	 * The intent of this loop is to gather information related to key
	 * changes.
	 */
	for (int c = 0; c < cfg->col_size; c++) {
		/* Check if there was an update from the previous scan */
		row_changed = matrix_new_state[c] ^ cfg->matrix_previous_state[c];

		if (!row_changed) {
			continue;
		}

		for (int r = 0; r < cfg->row_size; r++) {
			uint8_t cyc_idx = c * cfg->row_size + r;

			/*
			 * Index all they keys that changed for each row in
			 * order to debounce each key in terms of it
			 */
			if (row_changed & BIT(r)) {
				cfg->scan_cycle_idx[cyc_idx] = data->scan_cycles_idx;
			}
		}

		cfg->matrix_unstable_state[c] |= row_changed;
		cfg->matrix_previous_state[c] = matrix_new_state[c];
	}

	for (int c = 0; c < cfg->col_size; c++) {
		deb_col = cfg->matrix_unstable_state[c];

		if (!deb_col) {
			continue;
		}

		/* Debouncing for each row key occurs here */
		for (int r = 0; r < cfg->row_size; r++) {
			kbd_row_t mask = BIT(r);
			kbd_row_t row_bit = matrix_new_state[c] & mask;

			/* Continue if we already debounce a key */
			if (!(deb_col & mask)) {
				continue;
			}

			uint8_t cyc_idx = c * cfg->row_size + r;
			uint8_t scan_cyc_idx = cfg->scan_cycle_idx[cyc_idx];
			uint32_t scan_clk_cycle = data->scan_clk_cycle[scan_cyc_idx];

			/* Convert the clock cycle differences to usec */
			uint32_t deb_t_us = k_cyc_to_us_floor32(cycles_now - scan_clk_cycle);

			/* Does the key requires more time to be debounced? */
			if (deb_t_us < (row_bit ? cfg->debounce_down_us : cfg->debounce_up_us)) {
				/* Need more time to debounce */
				continue;
			}

			cfg->matrix_unstable_state[c] &= ~mask;

			/* Check if there was a change in the stable state */
			if ((cfg->matrix_stable_state[c] & mask) == row_bit) {
				/* Key state did not change */
				continue;
			}

			/*
			 * The current row has been debounced, therefore update
			 * the stable state. Then, proceed to notify the
			 * application about the keys pressed.
			 */
			cfg->matrix_stable_state[c] ^= mask;

			input_report_abs(dev, INPUT_ABS_X, c, false, K_FOREVER);
			input_report_abs(dev, INPUT_ABS_Y, r, false, K_FOREVER);
			input_report_key(dev, INPUT_BTN_TOUCH, row_bit, true, K_FOREVER);
		}
	}

	data->scan_cycles_idx = (data->scan_cycles_idx + 1) % INPUT_KBD_MATRIX_SCAN_OCURRENCES;
}

static bool input_kbd_matrix_check_key_events(const struct device *dev)
{
	const struct input_kbd_matrix_common_config *cfg = dev->config;
	bool key_pressed;

	/* Scan the matrix */
	key_pressed = input_kbd_matrix_scan(dev);

	for (int c = 0; c < cfg->col_size; c++) {
		LOG_DBG("c=%2d u=" PRIkbdrow " p=" PRIkbdrow " n=" PRIkbdrow,
			c,
			cfg->matrix_unstable_state[c],
			cfg->matrix_previous_state[c],
			cfg->matrix_new_state[c]);
	}

	/* Abort if ghosting is detected */
	if (cfg->ghostkey_check && input_kbd_matrix_ghosting(dev)) {
		return key_pressed;
	}

	input_kbd_matrix_update_state(dev);

	return key_pressed;
}

static k_timepoint_t input_kbd_matrix_poll_timeout(const struct device *dev)
{
	const struct input_kbd_matrix_common_config *cfg = dev->config;

	if (cfg->poll_timeout_ms == 0) {
		return sys_timepoint_calc(K_FOREVER);
	}

	return sys_timepoint_calc(K_MSEC(cfg->poll_timeout_ms));
}

static void input_kbd_matrix_poll(const struct device *dev)
{
	const struct input_kbd_matrix_common_config *cfg = dev->config;
	k_timepoint_t poll_time_end;
	uint32_t current_cycles;
	uint32_t cycles_diff;
	uint32_t wait_period_us;

	poll_time_end = input_kbd_matrix_poll_timeout(dev);

	while (true) {
		uint32_t start_period_cycles = k_cycle_get_32();

		if (input_kbd_matrix_check_key_events(dev)) {
			poll_time_end = input_kbd_matrix_poll_timeout(dev);
		} else if (sys_timepoint_expired(poll_time_end)) {
			break;
		}

		/*
		 * Subtract the time invested from the sleep period in order to
		 * compensate for the time invested in debouncing a key
		 */
		current_cycles = k_cycle_get_32();
		cycles_diff = current_cycles - start_period_cycles;
		wait_period_us = cfg->poll_period_us - k_cyc_to_us_floor32(cycles_diff);

		wait_period_us = CLAMP(wait_period_us,
				       USEC_PER_MSEC, cfg->poll_period_us);

		LOG_DBG("wait_period_us: %d", wait_period_us);

		/* Allow other threads to run while we sleep */
		k_usleep(wait_period_us);
	}
}

static void input_kbd_matrix_polling_thread(void *arg1, void *unused2, void *unused3)
{
	const struct device *dev = arg1;
	const struct input_kbd_matrix_common_config *cfg = dev->config;
	const struct input_kbd_matrix_api *api = cfg->api;
	struct input_kbd_matrix_common_data *data = dev->data;

	ARG_UNUSED(unused2);
	ARG_UNUSED(unused3);

	while (true) {
		input_kbd_matrix_drive_column(dev, INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL);
		api->set_detect_mode(dev, true);

		/* Check the rows again after enabling the interrupt to catch
		 * any potential press since the last read.
		 */
		if (api->read_row(dev) != 0) {
			input_kbd_matrix_poll_start(dev);
		}

		k_sem_take(&data->poll_lock, K_FOREVER);
		LOG_DBG("scan start");

		/* Disable interrupt of KSI pins and start polling */
		api->set_detect_mode(dev, false);

		input_kbd_matrix_poll(dev);
	}
}

int input_kbd_matrix_common_init(const struct device *dev)
{
	struct input_kbd_matrix_common_data *data = dev->data;

	k_sem_init(&data->poll_lock, 0, 1);

	k_thread_create(&data->thread, data->thread_stack,
			K_KERNEL_STACK_SIZEOF(data->thread_stack),
			input_kbd_matrix_polling_thread, (void *)dev, NULL, NULL,
			CONFIG_INPUT_KBD_MATRIX_THREAD_PRIORITY, 0, K_NO_WAIT);

	k_thread_name_set(&data->thread, dev->name);

	return 0;
}

#if CONFIG_INPUT_KBD_ACTUAL_KEY_MASK_DYNAMIC
int input_kbd_matrix_actual_key_mask_set(const struct device *dev,
					  uint8_t row, uint8_t col, bool enabled)
{
	const struct input_kbd_matrix_common_config *cfg = dev->config;

	if (row >= cfg->row_size || col >= cfg->col_size) {
		return -EINVAL;
	}

	if (cfg->actual_key_mask == NULL) {
		LOG_WRN("actual-key-mask not defined for %s", dev->name);
		return -EINVAL;
	}

	WRITE_BIT(cfg->actual_key_mask[col], row, enabled);

	return 0;
}
#endif
