/*
 * 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;
}

