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

#include <errno.h>
#include <device.h>
#include <drivers/ps2.h>
#include <soc.h>
#include <logging/log.h>

#define LOG_LEVEL CONFIG_PS2_LOG_LEVEL
LOG_MODULE_REGISTER(ps2_mchp_xec);

/* in 50us units */
#define PS2_TIMEOUT 10000

struct ps2_xec_config {
	PS2_Type *base;
	u8_t girq_id;
	u8_t girq_bit;
	u8_t isr_nvic;
};

struct ps2_xec_data {
	ps2_callback_t callback_isr;
	struct k_sem tx_lock;
};

static int ps2_xec_configure(struct device *dev, ps2_callback_t callback_isr)
{
	const struct ps2_xec_config *config = dev->config->config_info;
	struct ps2_xec_data *data = dev->driver_data;
	PS2_Type *base = config->base;

	u8_t  __attribute__((unused)) dummy;

	if (!callback_isr) {
		return -EINVAL;
	}

	data->callback_isr = callback_isr;

	/* In case the self test for a PS2 device already finished and
	 * set the SOURCE bit to 1 we clear it before enabling the
	 * interrupts. Instances must be allocated before the BAT or
	 * the host may time out.
	 */
	MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit);
	dummy = base->TRX_BUFF;
	base->STATUS = MCHP_PS2_STATUS_RW1C_MASK;

	/* Enable FSM and init instance in rx mode*/
	base->CTRL = MCHP_PS2_CTRL_EN_POS;

	/* We enable the interrupts in the EC aggregator so that the
	 * result  can be forwarded to the ARM NVIC
	 */
	MCHP_GIRQ_ENSET(config->girq_id) = BIT(config->girq_bit);

	k_sem_give(&data->tx_lock);

	return 0;
}


static int ps2_xec_write(struct device *dev, u8_t value)
{
	const struct ps2_xec_config *config = dev->config->config_info;
	struct ps2_xec_data *data = dev->driver_data;
	PS2_Type *base = config->base;
	int i = 0;

	u8_t  __attribute__((unused)) dummy;

	if (k_sem_take(&data->tx_lock, K_NO_WAIT)) {
		return -EACCES;
	}
	/* Allow the PS2 controller to complete a RX transaction. This
	 * is because the channel may be actively receiving data.
	 * In addition, it is necessary to wait for a previous TX
	 * transaction to complete. The PS2 block has a single
	 * FSM.
	 */
	while (((base->STATUS &
		(MCHP_PS2_STATUS_RXD_RDY | MCHP_PS2_STATUS_TX_IDLE))
		!= MCHP_PS2_STATUS_TX_IDLE) && (i < PS2_TIMEOUT)) {
		k_busy_wait(50);
		i++;
	}

	if (unlikely(i == PS2_TIMEOUT)) {
		LOG_DBG("PS2 write timed out");
		return -ETIMEDOUT;
	}

	/* Inhibit ps2 controller and clear status register */
	base->CTRL = 0x00;

	/* Read to clear data ready bit in the status register*/
	dummy = base->TRX_BUFF;

	base->STATUS = MCHP_PS2_STATUS_RW1C_MASK;
	/* Switch the interface to TX mode and enable state machine */
	base->CTRL = MCHP_PS2_CTRL_TR_TX | MCHP_PS2_CTRL_EN;

	/* Write value to TX/RX register */
	base->TRX_BUFF = value;

	k_sem_give(&data->tx_lock);

	return 0;
}

static int ps2_xec_inhibit_interface(struct device *dev)
{
	const struct ps2_xec_config *config = dev->config->config_info;
	struct ps2_xec_data *data = dev->driver_data;
	PS2_Type *base = config->base;

	if (k_sem_take(&data->tx_lock, K_MSEC(10)) != 0) {
		return -EACCES;
	}

	base->CTRL = 0x00;
	MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit);
	NVIC_ClearPendingIRQ(config->isr_nvic);

	k_sem_give(&data->tx_lock);

	return 0;
}

static int ps2_xec_enable_interface(struct device *dev)
{
	const struct ps2_xec_config *config = dev->config->config_info;
	struct ps2_xec_data *data = dev->driver_data;
	PS2_Type *base = config->base;

	MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit);
	base->CTRL = MCHP_PS2_CTRL_EN;

	k_sem_give(&data->tx_lock);

	return 0;
}
static void ps2_xec_isr(void *arg)
{
	struct device *dev = (struct device *)arg;
	const struct ps2_xec_config *config = dev->config->config_info;
	struct ps2_xec_data *data = dev->driver_data;
	PS2_Type *base = config->base;
	u32_t status;

	MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit);

	/* Read and clear status */
	status = base->STATUS;

	if (status & MCHP_PS2_STATUS_RXD_RDY) {
		base->CTRL = 0x00;
		if (data->callback_isr) {
			data->callback_isr(dev, base->TRX_BUFF);
		}
	} else if (status &
		    (MCHP_PS2_STATUS_TX_TMOUT | MCHP_PS2_STATUS_TX_ST_TMOUT)) {
		/* Clear sticky bits and go to read mode */
		base->STATUS = MCHP_PS2_STATUS_RW1C_MASK;
		LOG_ERR("TX time out");
	}

	/* The control register reverts to RX automatically after
	 * transmiting the data
	 */
	base->CTRL = MCHP_PS2_CTRL_EN;
}

static const struct ps2_driver_api ps2_xec_driver_api = {
	.config = ps2_xec_configure,
	.read = NULL,
	.write = ps2_xec_write,
	.disable_callback = ps2_xec_inhibit_interface,
	.enable_callback = ps2_xec_enable_interface,
};

#ifdef CONFIG_PS2_XEC_0
static int ps2_xec_init_0(struct device *dev);

static const struct ps2_xec_config ps2_xec_config_0 = {
	.base = (PS2_Type *) DT_PS2_XEC_0_BASE_ADDR,
	.girq_id = MCHP_GIRQ18_ID,
	.girq_bit = MCHP_PS2_0_GIRQ_POS,
	.isr_nvic = DT_PS2_XEC_0_IRQ,
};

static struct ps2_xec_data ps2_xec_port_data_0;

DEVICE_AND_API_INIT(ps2_xec_0, DT_PS2_XEC_0_LABEL,
		    &ps2_xec_init_0,
		    &ps2_xec_port_data_0, &ps2_xec_config_0,
		    POST_KERNEL, CONFIG_PS2_INIT_PRIORITY,
		    &ps2_xec_driver_api);


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

	struct ps2_xec_data *data = dev->driver_data;

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

	IRQ_CONNECT(DT_PS2_XEC_0_IRQ,
		    DT_PS2_XEC_0_IRQ_PRIORITY,
		    ps2_xec_isr, DEVICE_GET(ps2_xec_0), 0);

	irq_enable(DT_PS2_XEC_0_IRQ);

	return 0;
}
#endif /* CONFIG_PS2_XEC_0 */

#ifdef CONFIG_PS2_XEC_1
static int ps2_xec_init_1(struct device *dev);

static const struct ps2_xec_config ps2_xec_config_1 = {
	.base = (PS2_Type *) DT_PS2_XEC_1_BASE_ADDR,
	.girq_id = MCHP_GIRQ18_ID,
	.girq_bit = MCHP_PS2_1_GIRQ_POS,
	.isr_nvic = DT_PS2_XEC_1_IRQ,

};

static struct ps2_xec_data ps2_xec_port_data_1;

DEVICE_AND_API_INIT(ps2_xec_1, DT_PS2_XEC_1_LABEL,
		    &ps2_xec_init_1,
		    &ps2_xec_port_data_1, &ps2_xec_config_1,
		    POST_KERNEL, CONFIG_PS2_INIT_PRIORITY,
		    &ps2_xec_driver_api);

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

	struct ps2_xec_data *data = dev->driver_data;

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

	IRQ_CONNECT(DT_PS2_XEC_1_IRQ,
		    DT_PS2_XEC_1_IRQ_PRIORITY,
		    ps2_xec_isr, DEVICE_GET(ps2_xec_1), 0);

	irq_enable(DT_PS2_XEC_1_IRQ);

	return 0;
}
#endif /* CONFIG_PS2_XEC_1 */
