/*
 * Copyright (c) 2021 ITE Corporation. All Rights Reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ite_it8xxx2_uart

#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/kernel.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/policy.h>
#include <soc.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(uart_ite_it8xxx2, CONFIG_UART_LOG_LEVEL);

#if defined(CONFIG_PM_DEVICE) && defined(CONFIG_UART_CONSOLE_INPUT_EXPIRED)
static struct uart_it8xxx2_data *uart_console_data;
#endif

struct uart_it8xxx2_config {
	uint8_t port;
	/* GPIO cells */
	struct gpio_dt_spec gpio_wui;
	/* UART handle */
	const struct device *uart_dev;
	/* UART alternate configuration */
	const struct pinctrl_dev_config *pcfg;
};

struct uart_it8xxx2_data {
#ifdef CONFIG_UART_CONSOLE_INPUT_EXPIRED
	struct k_work_delayable rx_refresh_timeout_work;
#endif
};

enum uart_port_num {
	UART1 = 1,
	UART2,
};

#ifdef CONFIG_PM_DEVICE
void uart1_wui_isr(const struct device *gpio, struct gpio_callback *cb,
		   uint32_t pins)
{
	/* Disable interrupts on UART1 RX pin to avoid repeated interrupts. */
	(void)gpio_pin_interrupt_configure(gpio, (find_msb_set(pins) - 1),
					   GPIO_INT_DISABLE);

	/* Refresh console expired time if got UART Rx wake-up event */
#ifdef CONFIG_UART_CONSOLE_INPUT_EXPIRED
	k_timeout_t delay = K_MSEC(CONFIG_UART_CONSOLE_INPUT_EXPIRED_TIMEOUT);

	/*
	 * The pm state of it8xxx2 chip only supports standby, so here we
	 * can directly set the constraint for standby.
	 */
	pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
	k_work_reschedule(&uart_console_data->rx_refresh_timeout_work, delay);
#endif
}

void uart2_wui_isr(const struct device *gpio, struct gpio_callback *cb,
		   uint32_t pins)
{
	/* Disable interrupts on UART2 RX pin to avoid repeated interrupts. */
	(void)gpio_pin_interrupt_configure(gpio, (find_msb_set(pins) - 1),
					   GPIO_INT_DISABLE);

	/* Refresh console expired time if got UART Rx wake-up event */
#ifdef CONFIG_UART_CONSOLE_INPUT_EXPIRED
	k_timeout_t delay = K_MSEC(CONFIG_UART_CONSOLE_INPUT_EXPIRED_TIMEOUT);

	/*
	 * The pm state of it8xxx2 chip only supports standby, so here we
	 * can directly set the constraint for standby.
	 */
	pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
	k_work_reschedule(&uart_console_data->rx_refresh_timeout_work, delay);
#endif
}

static inline int uart_it8xxx2_pm_action(const struct device *dev,
					 enum pm_device_action action)
{
	const struct uart_it8xxx2_config *const config = dev->config;
	int ret = 0;

	switch (action) {
	/* Next device power state is in active. */
	case PM_DEVICE_ACTION_RESUME:
		/* Nothing to do. */
		break;
	/* Next device power state is deep doze mode */
	case PM_DEVICE_ACTION_SUSPEND:
		/* Enable UART WUI */
		ret = gpio_pin_interrupt_configure_dt(&config->gpio_wui,
						      GPIO_INT_MODE_EDGE | GPIO_INT_TRIG_LOW);
		if (ret < 0) {
			LOG_ERR("Failed to configure UART%d WUI (ret %d)",
				config->port, ret);
			return ret;
		}

		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

#ifdef CONFIG_UART_CONSOLE_INPUT_EXPIRED
static void uart_it8xxx2_rx_refresh_timeout(struct k_work *work)
{
	ARG_UNUSED(work);

	pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
}
#endif
#endif /* CONFIG_PM_DEVICE */


static int uart_it8xxx2_init(const struct device *dev)
{
	const struct uart_it8xxx2_config *const config = dev->config;
	int status;

	/* Set the pin to UART alternate function. */
	status = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
	if (status < 0) {
		LOG_ERR("Failed to configure UART pins");
		return status;
	}

#ifdef CONFIG_PM_DEVICE
	const struct device *uart_console_dev =
		DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
	int ret = 0;

	/*
	 * If the UART is used as a console device, we need to configure
	 * UART Rx interrupt as wakeup source and initialize a delayable
	 * work for console expired time.
	 */
	if (config->uart_dev == uart_console_dev) {
#ifdef CONFIG_UART_CONSOLE_INPUT_EXPIRED
		uart_console_data = dev->data;
		k_work_init_delayable(&uart_console_data->rx_refresh_timeout_work,
				      uart_it8xxx2_rx_refresh_timeout);
#endif
		/*
		 * When the system enters deep doze, all clocks are gated only the
		 * 32.768k clock is active. We need to wakeup EC by configuring
		 * UART Rx interrupt as a wakeup source. When the interrupt of UART
		 * Rx falling, EC will be woken.
		 */
		if (config->port == UART1) {
			static struct gpio_callback uart1_wui_cb;

			gpio_init_callback(&uart1_wui_cb, uart1_wui_isr,
					   BIT(config->gpio_wui.pin));

			ret = gpio_add_callback(config->gpio_wui.port, &uart1_wui_cb);
		} else if (config->port == UART2) {
			static struct gpio_callback uart2_wui_cb;

			gpio_init_callback(&uart2_wui_cb, uart2_wui_isr,
					   BIT(config->gpio_wui.pin));

			ret = gpio_add_callback(config->gpio_wui.port, &uart2_wui_cb);
		}

		if (ret < 0) {
			LOG_ERR("Failed to add UART%d callback (err %d)",
				config->port, ret);
			return ret;
		}
	}
#endif /* CONFIG_PM_DEVICE */

	return 0;
}

#define UART_ITE_IT8XXX2_INIT(inst)                                            \
	PINCTRL_DT_INST_DEFINE(inst);                                          \
	static const struct uart_it8xxx2_config uart_it8xxx2_cfg_##inst = {    \
		.port = DT_INST_PROP(inst, port_num),                          \
		.gpio_wui = GPIO_DT_SPEC_INST_GET(inst, gpios),                \
		.uart_dev = DEVICE_DT_GET(DT_INST_PHANDLE(inst, uart_dev)),    \
		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),                  \
	};                                                                     \
									       \
	static struct uart_it8xxx2_data uart_it8xxx2_data_##inst;              \
									       \
	PM_DEVICE_DT_INST_DEFINE(inst, uart_it8xxx2_pm_action);                \
	DEVICE_DT_INST_DEFINE(inst, &uart_it8xxx2_init,                        \
			      PM_DEVICE_DT_INST_GET(inst),                     \
			      &uart_it8xxx2_data_##inst,                       \
			      &uart_it8xxx2_cfg_##inst,                        \
			      PRE_KERNEL_1,                                    \
			      CONFIG_SERIAL_INIT_PRIORITY,                     \
			      NULL);

DT_INST_FOREACH_STATUS_OKAY(UART_ITE_IT8XXX2_INIT)
