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

#define DT_DRV_COMPAT microchip_xec_ps2

#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;
	uint8_t girq_id;
	uint8_t girq_bit;
	uint8_t isr_nvic;
};

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

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

	uint8_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(const struct device *dev, uint8_t value)
{
	const struct ps2_xec_config *config = dev->config;
	struct ps2_xec_data *data = dev->data;
	PS2_Type *base = config->base;
	int i = 0;

	uint8_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_RX_BUSY | 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;
	k_sleep(K_MSEC(1));
	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(const struct device *dev)
{
	const struct ps2_xec_config *config = dev->config;
	struct ps2_xec_data *data = dev->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(const struct device *dev)
{
	const struct ps2_xec_config *config = dev->config;
	struct ps2_xec_data *data = dev->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(const struct device *dev)
{
	const struct ps2_xec_config *config = dev->config;
	struct ps2_xec_data *data = dev->data;
	PS2_Type *base = config->base;
	uint32_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: %0x", status);
	}

	/* The control register reverts to RX automatically after
	 * transmitting 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(const struct device *dev);

static const struct ps2_xec_config ps2_xec_config_0 = {
	.base = (PS2_Type *) DT_INST_REG_ADDR(0),
	.girq_id = DT_INST_PROP(0, girq),
	.girq_bit = DT_INST_PROP(0, girq_bit),
	.isr_nvic = DT_INST_IRQN(0),
};

static struct ps2_xec_data ps2_xec_port_data_0;

DEVICE_DT_INST_DEFINE(0,
		    &ps2_xec_init_0,
		    NULL,
		    &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(const struct device *dev)
{
	ARG_UNUSED(dev);

	struct ps2_xec_data *data = dev->data;

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

	IRQ_CONNECT(DT_INST_IRQN(0),
		    DT_INST_IRQ(0, priority),
		    ps2_xec_isr, DEVICE_DT_INST_GET(0), 0);

	irq_enable(DT_INST_IRQN(0));

	return 0;
}
#endif /* CONFIG_PS2_XEC_0 */

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

static const struct ps2_xec_config ps2_xec_config_1 = {
	.base = (PS2_Type *) DT_INST_REG_ADDR(1),
	.girq_id = DT_INST_PROP(1, girq),
	.girq_bit = DT_INST_PROP(1, girq_bit),
	.isr_nvic = DT_INST_IRQN(1),

};

static struct ps2_xec_data ps2_xec_port_data_1;

DEVICE_DT_INST_DEFINE(1,
		    &ps2_xec_init_1,
		    NULL,
		    &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(const struct device *dev)
{
	ARG_UNUSED(dev);

	struct ps2_xec_data *data = dev->data;

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

	IRQ_CONNECT(DT_INST_IRQN(1),
		    DT_INST_IRQ(1, priority),
		    ps2_xec_isr, DEVICE_DT_INST_GET(1), 0);

	irq_enable(DT_INST_IRQN(1));

	return 0;
}
#endif /* CONFIG_PS2_XEC_1 */
