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

#include <zephyr.h>
#include <sys/printk.h>
#include <drivers/gpio.h>
#include <soc.h>
#include <drivers/kscan.h>

#define LOG_LEVEL LOG_LEVEL_DBG
#include <logging/log.h>

LOG_MODULE_REGISTER(main);

#define KSCAN_NODE DT_ALIAS(kscan0)

const struct device *kscan_dev = DEVICE_DT_GET(KSCAN_NODE);
static struct k_timer typematic_timer;
static struct k_timer block_matrix_timer;

#define KEY_RSVD 0U
#define MAX_MATRIX_KEY_COLS 16
#define MAX_MATRIX_KEY_ROWS 8

/****************************************************************************/
/*  Fujitsu keyboard model N860-7401-TOO1                                   */
/*                                                                          */
/*  Sense7  Sense6  Sense5  Sense4  Sense3  Sense2  Sense1  Sense0          */
/*+---------------------------------------------------------------+         */
/*|       | Capslk|       |   1!  |  Tab  |   F1  |   `~  |       | Scan  0 */
/*|       |  (30) |       |  (2)  |  (16) | (112) |  (1)  |       | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*|       |   W   |   Q   |   F7  |       |  Esc  |   F6  |   F5  | Scan  1 */
/*|       |  (18) |  (17) | (118) |       | (110) | (117) | (116) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*|       |   F8  |       |   2@  |   F4  |   F3  |       |   F2  | Scan  2 */
/*|       | (119) |       |  (3)  | (115) | (114) |       | (113) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*|       |   R   |   E   |   3#  |   4$  |   C   |   F   |   V   | Scan  3 */
/*|       |  (20) |  (19) |  (4)  |  (5)  |  (48) |  (34) |  (49) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*|   N   |   Y   |   6^  |   5%  |   B   |   T   |   H   |   G   | Scan  4 */
/*|  (51) |  (22) |  (7)  |  (6)  | (50)  |  (21) |  (36) |  (35) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*| SpaceB|   M   |   A   |   7&  |   J   |   D   |   S   |   U   | Scan  5 */
/*|  (61) |  (52) |  (31) |  (8)  |  (37) |  (33) |  (32) |  (23) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*|   F9  |   I   |   ,<  |   8*  |       |   Z   |   X   |   K   | Scan  6 */
/*| (120) |  (24) |  (53) |  (9)  |       |  (46) |  (47) |  (38) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*|       |   =+  |   ]}  |   9(  |   L   |       |  CRSL |   O   | Scan  7 */
/*|       |  (13) |  (28) |  (10) |  (39) |       |  (79) |  (25) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*|   -_  |   0)  |   /?  |   [{  |   ;:  |       |       |   '"  | Scan  8 */
/*|  (12) |  (11) |  (55) |  (27) |  (40) |       |       |  (41) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*|  F10  | Pause | NumLK |   P   |       |       |       |       | Scan  9 */
/*| (121) | (126) |  (90) |  (26) |       |       |       |       | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*| BkSpac|   \|  |  F11  |   .>  |       |       | W-Appl|  CRSD | Scan 10 */
/*|  (15) |  (29) | (122) |  (54) |       |       |  (71) |  (84) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*| Enter | Delete| Insert|  F12  |       |       |  CRSU |  CRSR | Scan 11 */
/*|  (43) |  (76) |  (75) | (123) |       |       |  (83) |  (89) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*|       | R-WIN |       |       |       |       | L-WIN |   Fn  | Scan 12 */
/*|       |  (87) |       |       |       |       |  (59) | (255) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*|       |       |       | RShift| LShift|       |       |       | Scan 13 */
/*|       |       |       |  (57) |  (44) |       |       |       | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*|       |       |       |       |       |       | L Alt | R Alt | Scan 14 */
/*|       |       |       |       |       |       |  (60) |  (62) | (KEY #) */
/*|-------+-------+-------+-------+-------+-------+-------+-------|         */
/*| R Ctrl|       |       |       |       | L Ctrl|       |       | Scan 15 */
/*|  (64) |       |       |       |       |  (58) |       |       | (KEY #) */
/*+---------------------------------------------------------------+         */
/*                                                                          */
/****************************************************************************/

static const uint8_t keymap[MAX_MATRIX_KEY_COLS][MAX_MATRIX_KEY_ROWS] = {
	{KEY_RSVD, 1, 112, 16, 2, KEY_RSVD, 30, KEY_RSVD},
	{116, 117, 110, KEY_RSVD, 118, 17, 18, KEY_RSVD},
	{113, KEY_RSVD, 114, 115, 3, KEY_RSVD, 119, KEY_RSVD},
	{49, 34, 48, 5, 4, 19, 20, KEY_RSVD},
	{35, 36, 21, 50, 6, 7, 22, 51},
	{23, 32, 33, 37, 8, 31, 52, 61},
	{38, 47, 46, KEY_RSVD, 9, 53, 24, 120},
	{25, 79, KEY_RSVD, 39, 10, 28, 13, KEY_RSVD},
	{41, KEY_RSVD, KEY_RSVD, 40, 27, 55, 11, 12},
	{KEY_RSVD, KEY_RSVD, KEY_RSVD, KEY_RSVD, 26, 90, 126, 121},
	{84, 71, KEY_RSVD, KEY_RSVD, 54, 122, 29, 15},
	{89, 83, KEY_RSVD, KEY_RSVD, 123, 75, 76, 43},
	{255, 59, KEY_RSVD, KEY_RSVD, KEY_RSVD, KEY_RSVD, 87, KEY_RSVD},
	{KEY_RSVD, KEY_RSVD, 44, 57, KEY_RSVD, KEY_RSVD, KEY_RSVD},
	{62, 60, KEY_RSVD, KEY_RSVD, KEY_RSVD, KEY_RSVD, KEY_RSVD, KEY_RSVD},
	{KEY_RSVD, KEY_RSVD, 58, KEY_RSVD, KEY_RSVD, KEY_RSVD, KEY_RSVD, 64},
};

/* Key used for typematic */
static uint8_t last_key;

/* Typematic rate and delay values correspond to the data passed after
 * the F3 command (See the 8042 spec online)
 */
static const uint16_t period[] = {
	33U,  37U,  42U,  46U,  50U,  54U,  58U,  63U,
	67U,  75U,  83U,  92U, 100U, 109U, 116U, 125U,
	133U, 149U, 167U, 182U, 200U, 217U, 232U, 250U,
	270U, 303U, 333U, 370U, 400U, 435U, 470U, 500U
};

static const uint16_t delay[] = { 250U, 500U, 750U, 1000U };

static bool block_kb_matrix;

static void typematic_callback(struct k_timer *timer)
{
	LOG_INF("Typematic : %u\n", last_key);
}

static void kb_callback(const struct device *dev, uint32_t row, uint32_t col,
			bool pressed)
{
	ARG_UNUSED(dev);
	last_key = keymap[col][row];

	LOG_INF("Key code = %u Pressed = %u\n", last_key, pressed);

	if (pressed) {
		k_timer_start(&typematic_timer,
			      K_MSEC(delay[0]), K_MSEC(period[0]));
	} else {
		k_timer_stop(&typematic_timer);
	}
}

static void block_matrix_callback(struct k_timer *timer)
{
	LOG_DBG("block host : %d\n", block_kb_matrix);
	if (block_kb_matrix) {
		kscan_disable_callback(kscan_dev);
		block_kb_matrix = false;
		k_timer_stop(&typematic_timer);
	} else {
		kscan_enable_callback(kscan_dev);
		block_kb_matrix = true;
	}
}

void main(void)
{
	printk("Kscan matrix sample application\n");

	if (!device_is_ready(kscan_dev)) {
		LOG_ERR("kscan device %s not ready", kscan_dev->name);
		return;
	}

	kscan_config(kscan_dev, kb_callback);
	k_timer_init(&typematic_timer, typematic_callback, NULL);
	k_timer_init(&block_matrix_timer, block_matrix_callback, NULL);
	k_timer_start(&block_matrix_timer, K_SECONDS(1), K_SECONDS(3));

}
