/*
 * 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
	 * 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(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,
		    device_pm_control_nop,
		    &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,
		    device_pm_control_nop,
		    &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 */
