/*
 * Copyright (c) 2019 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <device.h>
#include <drivers/kscan.h>
#include <kernel.h>
#include <soc.h>
#include <sys/atomic.h>
#include <logging/log.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 onthe 32KHz clock with 30 usec clock cycles */
#define CLOCK_32K_HW_CYCLES_TO_US(X) \
	(u32_t)((((u64_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_data {
	/* variables in usec units */
	u32_t deb_time_press;
	u32_t deb_time_rel;
	s64_t poll_timeout;
	u32_t poll_period;
	u8_t matrix_stable_state[MAX_MATRIX_KEY_COLS];
	u8_t matrix_unstable_state[MAX_MATRIX_KEY_COLS];
	u8_t matrix_previous_state[MAX_MATRIX_KEY_COLS];
	/* Index in to the scan_clock_cycle to indicate start of debouncing */
	u8_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
	 */
	u8_t scan_clk_cycle[SCAN_OCURRENCES];
	struct k_sem poll_lock;
	u8_t scan_cycles_idx;
	kscan_callback_t callback;
	struct k_thread thread;
	atomic_t enable_scan;

	K_THREAD_STACK_MEMBER(thread_stack, TASK_STACK_SIZE);
};

static KSCAN_Type *base = (KSCAN_Type *)
	(DT_INST_0_MICROCHIP_XEC_KSCAN_BASE_ADDRESS);

static struct kscan_xec_data kbd_data;

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

static u8_t read_keyboard_row(void)
{
	/* In this implementation a 1 means key pressed */
	return ~(base->KSI_IN & 0xFF);
}

static bool is_matrix_ghosting(const uint8_t *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 <  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 colums using z&(z-1) which is
			 * non-zero only if z has more than one bit set.
			 */
			u8_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(u8_t *new_state)
{
	u8_t row;
	u8_t key_event = 0U;

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

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

	drive_keyboard_column(KEYBOARD_COLUMN_DRIVE_NONE);

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

static void scan_matrix_xec_isr(void *arg)
{
	ARG_UNUSED(arg);

	MCHP_GIRQ_SRC(MCHP_KSCAN_GIRQ) = BIT(MCHP_KSCAN_GIRQ_POS);
	irq_disable(DT_INST_0_MICROCHIP_XEC_KSCAN_IRQ_0);
	k_sem_give(&kbd_data.poll_lock);
	LOG_DBG(" ");
}

static bool check_key_events(void *dev)
{
	u8_t matrix_new_state[MAX_MATRIX_KEY_COLS] = {0U};
	bool key_pressed = false;
	u32_t cycles_now  = k_cycle_get_32();

	if (++kbd_data.scan_cycles_idx >= SCAN_OCURRENCES)
		kbd_data.scan_cycles_idx = 0U;

	kbd_data.scan_clk_cycle[kbd_data.scan_cycles_idx] = cycles_now;

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

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

	u8_t row_changed = 0U;
	u8_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] ^
					kbd_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))
				kbd_data.scan_cycle_idx[c][r] =
					kbd_data.scan_cycles_idx;
		}

		kbd_data.matrix_unstable_state[c] |= row_changed;
		kbd_data.matrix_previous_state[c] = matrix_new_state[c];
	}

	for (int c = 0; c < MAX_MATRIX_KEY_COLS; c++) {
		deb_col = kbd_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++) {
			u8_t mask = BIT(r);
			u8_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 */
			u32_t debt = CLOCK_32K_HW_CYCLES_TO_US(cycles_now -
			kbd_data.scan_clk_cycle[kbd_data.scan_cycle_idx[c][r]]);

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

			kbd_data.matrix_unstable_state[c] &= ~row_bit;

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

	return key_pressed;
}

static bool poll_expired(u32_t start_cycles, s64_t *timeout)
{
	u32_t stop_cycles;
	u32_t cycles_spent;
	u32_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(void *dev, void *dummy2, void *dummy3)
{
	u32_t current_cycles;
	u32_t cycles_diff;
	u32_t wait_period;
	s64_t local_poll_timeout = kbd_data.poll_timeout;

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

		/* Ignore isr when releasing a key as we are polling */
		MCHP_GIRQ_SRC(MCHP_KSCAN_GIRQ) = BIT(MCHP_KSCAN_GIRQ_POS);
		NVIC_ClearPendingIRQ(MCHP_KSAN_NVIC);
		irq_enable(MCHP_KSAN_NVIC);
		drive_keyboard_column(KEYBOARD_COLUMN_DRIVE_ALL);
		k_sem_take(&kbd_data.poll_lock, K_FOREVER);

		u32_t start_poll_cycles = k_cycle_get_32();

		while (atomic_get(&kbd_data.enable_scan) == 1U) {
			u32_t start_period_cycles = k_cycle_get_32();

			if (check_key_events(dev)) {
				local_poll_timeout = kbd_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 =  kbd_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 > kbd_data.poll_period) {
				LOG_DBG("wait_period : %u", wait_period);

				wait_period = kbd_data.poll_period;
			}

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

static int kscan_xec_configure(struct device *dev,
				 kscan_callback_t callback)
{
	ARG_UNUSED(dev);

	if (!callback) {
		return -EINVAL;
	}

	kbd_data.callback = callback;

	MCHP_GIRQ_ENSET(MCHP_KSCAN_GIRQ) = BIT(MCHP_KSCAN_GIRQ_POS);

	return 0;
}

static int kscan_xec_inhibit_interface(struct device *dev)
{
	ARG_UNUSED(dev);

	atomic_set(&kbd_data.enable_scan, 0);

	return 0;
}

static int kscan_xec_enable_interface(struct device *dev)
{
	ARG_UNUSED(dev);

	atomic_set(&kbd_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(struct device *dev);

DEVICE_AND_API_INIT(kscan_xec, DT_INST_0_MICROCHIP_XEC_KSCAN_LABEL,
		    &kscan_xec_init,
		    NULL, NULL,
		    POST_KERNEL, CONFIG_KSCAN_INIT_PRIORITY,
		    &kscan_xec_driver_api);


static int kscan_xec_init(struct device *dev)
{
	ARG_UNUSED(dev);

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

	/* Time figures are transformed from msec to usec */
	kbd_data.deb_time_press = (u32_t)
		(CONFIG_KSCAN_XEC_DEBOUNCE_DOWN * MSEC_PER_MS);
	kbd_data.deb_time_rel = (u32_t)
		(CONFIG_KSCAN_XEC_DEBOUNCE_UP * MSEC_PER_MS);
	kbd_data.poll_period = (u32_t)
		(CONFIG_KSCAN_XEC_POLL_PERIOD * MSEC_PER_MS);
	kbd_data.poll_timeout = 100 * MSEC_PER_MS;

	k_sem_init(&kbd_data.poll_lock, 0, 1);
	atomic_set(&kbd_data.enable_scan, 1);

	k_thread_create(&kbd_data.thread, kbd_data.thread_stack,
			TASK_STACK_SIZE,
			polling_task, dev, NULL, NULL,
			K_PRIO_COOP(4), 0, K_NO_WAIT);

	/* Interrupts are enabled in the thread function */
	IRQ_CONNECT(MCHP_KSAN_NVIC, 0, scan_matrix_xec_isr, NULL, 0);

	return 0;
}
