/*
 * Copyright (c) 2019 Intel Corporation
 * Copyright (c) 2022 Microchip Technology Inc.
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT microchip_xec_kscan

#include <zephyr/arch/arm/aarch32/cortex_m/cmsis.h>
#include <errno.h>
#include <zephyr/device.h>
#ifdef CONFIG_SOC_SERIES_MEC172X
#include <zephyr/drivers/clock_control/mchp_xec_clock_control.h>
#include <zephyr/drivers/interrupt_controller/intc_mchp_xec_ecia.h>
#endif
#include <zephyr/drivers/kscan.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/kernel.h>
#include <soc.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/logging/log.h>
#include <zephyr/irq.h>

#define LOG_LEVEL CONFIG_KSCAN_LOG_LEVEL
LOG_MODULE_REGISTER(kscan_mchp_xec);

#define MAX_MATRIX_KEY_COLS CONFIG_KSCAN_XEC_COLUMN_SIZE
#define MAX_MATRIX_KEY_ROWS CONFIG_KSCAN_XEC_ROW_SIZE

#define KEYBOARD_COLUMN_DRIVE_ALL       -2
#define KEYBOARD_COLUMN_DRIVE_NONE      -1

/* Poll period/debouncing rely on the 32KHz clock with 30 usec clock cycles */
#define CLOCK_32K_HW_CYCLES_TO_US(X) \
	(uint32_t)((((uint64_t)(X) * 1000000U) / sys_clock_hw_cycles_per_sec()))
/* Milliseconds in microseconds */
#define MSEC_PER_MS 1000U
/* Number of tracked scan times */
#define SCAN_OCURRENCES 30U
/* Thread stack size */
#define TASK_STACK_SIZE 1024

struct kscan_xec_config {
	struct kscan_regs *regs;
	uint8_t girq;
	uint8_t girq_pos;
	uint8_t irq_pri;
	uint8_t pcr_idx;
	uint8_t pcr_pos;
	uint8_t rsvd[3];
	const struct pinctrl_dev_config *pcfg;
};

struct kscan_xec_data {
	/* variables in usec units */
	uint32_t deb_time_press;
	uint32_t deb_time_rel;
	int64_t poll_timeout;
	uint32_t poll_period;
	uint8_t matrix_stable_state[MAX_MATRIX_KEY_COLS];
	uint8_t matrix_unstable_state[MAX_MATRIX_KEY_COLS];
	uint8_t matrix_previous_state[MAX_MATRIX_KEY_COLS];
	/* Index in to the scan_clock_cycle to indicate start of debouncing */
	uint8_t scan_cycle_idx[MAX_MATRIX_KEY_COLS][MAX_MATRIX_KEY_ROWS];
	/* Track previous "elapsed clock cycles" per matrix scan. This
	 * is used to calculate the debouncing time for every key
	 */
	uint8_t scan_clk_cycle[SCAN_OCURRENCES];
	struct k_sem poll_lock;
	uint8_t scan_cycles_idx;
	kscan_callback_t callback;
	struct k_thread thread;
	atomic_t enable_scan;

	K_KERNEL_STACK_MEMBER(thread_stack, TASK_STACK_SIZE);
};

#ifdef CONFIG_SOC_SERIES_MEC172X
static void kscan_clear_girq_status(const struct device *dev)
{
	struct kscan_xec_config const *cfg = dev->config;

	mchp_xec_ecia_girq_src_clr(cfg->girq, cfg->girq_pos);
}

static void kscan_configure_girq(const struct device *dev, bool enable)
{
	struct kscan_xec_config const *cfg = dev->config;

	if (enable) {
		mchp_xec_ecia_enable(cfg->girq, cfg->girq_pos);
	} else {
		mchp_xec_ecia_disable(cfg->girq, cfg->girq_pos);
	}
}

static void kscan_clr_slp_en(const struct device *dev)
{
	struct kscan_xec_config const *cfg = dev->config;

	z_mchp_xec_pcr_periph_sleep(cfg->pcr_idx, cfg->pcr_pos, 0);
}

#else
static void kscan_clear_girq_status(const struct device *dev)
{
	struct kscan_xec_config const *cfg = dev->config;

	MCHP_GIRQ_SRC(cfg->girq) = BIT(cfg->girq_pos);
}

static void kscan_configure_girq(const struct device *dev, bool enable)
{
	struct kscan_xec_config const *cfg = dev->config;

	if (enable) {
		MCHP_GIRQ_ENSET(cfg->girq) = BIT(cfg->girq_pos);
	} else {
		MCHP_GIRQ_ENCLR(cfg->girq) = BIT(cfg->girq_pos);
	}
}

static void kscan_clr_slp_en(const struct device *dev)
{
	ARG_UNUSED(dev);

	mchp_pcr_periph_slp_ctrl(PCR_KEYSCAN, 0);
}
#endif


static void drive_keyboard_column(const struct device *dev, int data)
{
	struct kscan_xec_config const *cfg = dev->config;
	struct kscan_regs *regs = cfg->regs;

	if (data == KEYBOARD_COLUMN_DRIVE_ALL) {
		/* KSO output controlled by the KSO_SELECT field */
		regs->KSO_SEL = MCHP_KSCAN_KSO_ALL;
	} else if (data == KEYBOARD_COLUMN_DRIVE_NONE) {
		/* Keyboard scan disabled. All KSO output buffers disabled */
		regs->KSO_SEL = MCHP_KSCAN_KSO_EN;
	} else {
		/* It is assumed, KEYBOARD_COLUMN_DRIVE_ALL was
		 * previously set
		 */
		regs->KSO_SEL = data;
	}
}

static uint8_t read_keyboard_row(const struct device *dev)
{
	struct kscan_xec_config const *cfg = dev->config;
	struct kscan_regs *regs = cfg->regs;

	/* In this implementation a 1 means key pressed */
	return ~(regs->KSI_IN & 0xFF);
}

static bool is_matrix_ghosting(const uint8_t *state)
{
	/* matrix keyboard designs are susceptible 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 <  MAX_MATRIX_KEY_COLS; c++) {
		if (!state[c])
			continue;

		for (int c_n = c + 1; c_n <  MAX_MATRIX_KEY_COLS; c_n++) {
			/* 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 columns using z&(z-1) which is
			 * non-zero only if z has more than one bit set.
			 */
			uint8_t common_row_bits = state[c] & state[c_n];

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

	return false;
}

static bool read_keyboard_matrix(const struct device *dev, uint8_t *new_state)
{
	uint8_t row;
	uint8_t key_event = 0U;

	for (int col = 0; col < MAX_MATRIX_KEY_COLS; col++) {
		drive_keyboard_column(dev, col);

		/* Allow the matrix to stabilize before reading it */
		k_busy_wait(50U);
		row = read_keyboard_row(dev);
		new_state[col] = row;
		key_event |= row;
	}

	drive_keyboard_column(dev, KEYBOARD_COLUMN_DRIVE_NONE);

	return key_event != 0U ? true : false;
}

static void scan_matrix_xec_isr(const struct device *dev)
{
	struct kscan_xec_data *const data = dev->data;

	kscan_clear_girq_status(dev);
	irq_disable(DT_INST_IRQN(0));
	k_sem_give(&data->poll_lock);
	LOG_DBG(" ");
}

static bool check_key_events(const struct device *dev)
{
	struct kscan_xec_data *const data = dev->data;
	uint8_t matrix_new_state[MAX_MATRIX_KEY_COLS] = {0U};
	bool key_pressed = false;
	uint32_t cycles_now  = k_cycle_get_32();

	if (++data->scan_cycles_idx >= SCAN_OCURRENCES) {
		data->scan_cycles_idx = 0U;
	}

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

	/* Scan the matrix */
	key_pressed = read_keyboard_matrix(dev, matrix_new_state);

	/* Abort if ghosting is detected */
	if (is_matrix_ghosting(matrix_new_state)) {
		return false;
	}

	uint8_t row_changed = 0U;
	uint8_t deb_col;

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

		if (!row_changed) {
			continue;
		}

		for (int r = 0; r < MAX_MATRIX_KEY_ROWS; 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)) {
				data->scan_cycle_idx[c][r] =
					data->scan_cycles_idx;
			}
		}

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

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

		if (!deb_col) {
			continue;
		}

		/* Debouncing for each row key occurs here */
		for (int r = 0; r < MAX_MATRIX_KEY_ROWS; r++) {
			uint8_t mask = BIT(r);
			uint8_t row_bit = matrix_new_state[c] & mask;

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

			/* Convert the clock cycle differences to usec */
			uint32_t debt = CLOCK_32K_HW_CYCLES_TO_US(cycles_now -
			data->scan_clk_cycle[data->scan_cycle_idx[c][r]]);

			/* Does the key requires more time to be debounced? */
			if (debt < (row_bit ? data->deb_time_press :
						data->deb_time_rel)) {
				/* Need more time to debounce */
				continue;
			}

			data->matrix_unstable_state[c] &= ~row_bit;

			/* Check if there was a change in the stable state */
			if ((data->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.
			 */
			data->matrix_stable_state[c] ^= mask;
			if (atomic_get(&data->enable_scan) == 1U) {
				data->callback(dev, r, c,
					       row_bit ? true : false);
			}
		}
	}

	return key_pressed;
}

static bool poll_expired(uint32_t start_cycles, int64_t *timeout)
{
	uint32_t stop_cycles;
	uint32_t cycles_spent;
	uint32_t microsecs_spent;

	stop_cycles = k_cycle_get_32();
	cycles_spent =  stop_cycles - start_cycles;
	microsecs_spent = CLOCK_32K_HW_CYCLES_TO_US(cycles_spent);

	/* Update the timeout value */
	*timeout -= microsecs_spent;

	return *timeout >= 0;

}

void polling_task(const struct device *dev, void *dummy2, void *dummy3)
{
	struct kscan_xec_config const *cfg = dev->config;
	struct kscan_xec_data *const data = dev->data;
	struct kscan_regs *regs = cfg->regs;
	uint32_t current_cycles;
	uint32_t cycles_diff;
	uint32_t wait_period;
	int64_t local_poll_timeout = data->poll_timeout;

	ARG_UNUSED(dummy2);
	ARG_UNUSED(dummy3);

	while (true) {
		regs->KSI_STS = MCHP_KSCAN_KSO_SEL_REG_MASK;

		/* Ignore isr when releasing a key as we are polling */
		kscan_clear_girq_status(dev);
		NVIC_ClearPendingIRQ(DT_INST_IRQN(0));
		irq_enable(DT_INST_IRQN(0));

		drive_keyboard_column(dev, KEYBOARD_COLUMN_DRIVE_ALL);

		k_sem_take(&data->poll_lock, K_FOREVER);

		uint32_t start_poll_cycles = k_cycle_get_32();

		while (atomic_get(&data->enable_scan) == 1U) {
			uint32_t start_period_cycles = k_cycle_get_32();

			if (check_key_events(DEVICE_DT_INST_GET(0))) {
				local_poll_timeout = data->poll_timeout;
				start_poll_cycles = k_cycle_get_32();
			} else if (!poll_expired(start_poll_cycles,
					      &local_poll_timeout)) {
				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 =  data->poll_period -
				CLOCK_32K_HW_CYCLES_TO_US(cycles_diff);

			/* Override wait_period in case it is less than 1 ms */
			if (wait_period < MSEC_PER_MS) {
				wait_period = MSEC_PER_MS;
			}

			/* wait period results in a larger number when
			 * current cycles counter wrap. In this case, the
			 * whole poll period is used
			 */
			if (wait_period > data->poll_period) {
				LOG_DBG("wait_period : %u", wait_period);

				wait_period = data->poll_period;
			}

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

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

	if (!callback) {
		return -EINVAL;
	}

	data->callback = callback;

	kscan_clear_girq_status(dev);
	kscan_configure_girq(dev, 1);

	return 0;
}

static int kscan_xec_inhibit_interface(const struct device *dev)
{
	struct kscan_xec_data *const data = dev->data;

	atomic_set(&data->enable_scan, 0);

	return 0;
}

static int kscan_xec_enable_interface(const struct device *dev)
{
	struct kscan_xec_data *const data = dev->data;

	atomic_set(&data->enable_scan, 1);

	return 0;
}

static const struct kscan_driver_api kscan_xec_driver_api = {
	.config = kscan_xec_configure,
	.disable_callback = kscan_xec_inhibit_interface,
	.enable_callback = kscan_xec_enable_interface,
};

static int kscan_xec_init(const struct device *dev)
{
	struct kscan_xec_config const *cfg = dev->config;
	struct kscan_xec_data *const data = dev->data;
	struct kscan_regs *regs = cfg->regs;

	int ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);

	if (ret != 0) {
		LOG_ERR("XEC KSCAN pinctrl init failed (%d)", ret);
		return ret;
	}

	kscan_clr_slp_en(dev);

	/* Enable predrive */
	regs->KSO_SEL |= BIT(MCHP_KSCAN_KSO_EN_POS);
	regs->EXT_CTRL = MCHP_KSCAN_EXT_CTRL_PREDRV_EN;
	regs->KSO_SEL &= ~BIT(MCHP_KSCAN_KSO_EN_POS);
	regs->KSI_IEN = MCHP_KSCAN_KSI_IEN_REG_MASK;

	/* Time figures are transformed from msec to usec */
	data->deb_time_press = (uint32_t)
		(CONFIG_KSCAN_XEC_DEBOUNCE_DOWN * MSEC_PER_MS);
	data->deb_time_rel = (uint32_t)
		(CONFIG_KSCAN_XEC_DEBOUNCE_UP * MSEC_PER_MS);
	data->poll_period = (uint32_t)
		(CONFIG_KSCAN_XEC_POLL_PERIOD * MSEC_PER_MS);
	data->poll_timeout = 100 * MSEC_PER_MS;

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

	k_thread_create(&data->thread, data->thread_stack,
			TASK_STACK_SIZE,
			(void (*)(void *, void *, void *))polling_task,
			(void *)dev, NULL, NULL,
			K_PRIO_COOP(4), 0, K_NO_WAIT);

	/* Interrupts are enabled in the thread function */
	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
		    scan_matrix_xec_isr, DEVICE_DT_INST_GET(0), 0);

	return 0;
}

static struct kscan_xec_data kbd_data;

PINCTRL_DT_INST_DEFINE(0);

static struct kscan_xec_config kscan_xec_cfg_0 = {
	.regs = (struct kscan_regs *)(DT_INST_REG_ADDR(0)),
	.girq = (uint8_t)(DT_INST_PROP_BY_IDX(0, girqs, 0)),
	.girq_pos = (uint8_t)(DT_INST_PROP_BY_IDX(0, girqs, 1)),
	.pcr_idx = (uint8_t)(DT_INST_PROP_BY_IDX(0, pcrs, 0)),
	.pcr_pos = (uint8_t)(DT_INST_PROP_BY_IDX(0, pcrs, 1)),
	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
};

DEVICE_DT_INST_DEFINE(0, kscan_xec_init,
		      NULL, &kbd_data, &kscan_xec_cfg_0,
		      POST_KERNEL, CONFIG_KSCAN_INIT_PRIORITY,
		      &kscan_xec_driver_api);
