/*
 * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <soc/periph_defs.h>
#include <limits.h>
#include <assert.h>
#include "soc/soc.h"
#include <soc.h>
#include <zephyr.h>
#include <drivers/interrupt_controller/intc_esp32c3.h>
#include <sw_isr_table.h>
#include <riscv/interrupt.h>

#define ESP32C3_INTC_DEFAULT_PRIO			15

#include <logging/log.h>
LOG_MODULE_REGISTER(intc_esp32c3, CONFIG_LOG_DEFAULT_LEVEL);

/*
 * Define this to debug the choices made when allocating the interrupt. This leads to much debugging
 * output within a critical region, which can lead to weird effects like e.g. the interrupt watchdog
 * being triggered, that is why it is separate from the normal LOG* scheme.
 */
#ifdef CONFIG_INTC_ESP32C3_DECISIONS_LOG
# define INTC_LOG(...) LOG_INF(__VA_ARGS__)
#else
# define INTC_LOG(...) do {} while (0)
#endif

#define ESP32C3_INTC_DEFAULT_PRIORITY   15
#define ESP32C3_INTC_DEFAULT_THRESHOLD  1
#define ESP32C3_INTC_DISABLED_SLOT      31
#define ESP32C3_INTC_SRCS_PER_IRQ       2
#define ESP32C3_INTC_AVAILABLE_IRQS     30

static uint32_t esp_intr_enabled_mask[2] = {0, 0};

static uint32_t esp_intr_find_irq_for_source(uint32_t source)
{
	/* in general case, each 2 sources goes routed to
	 * 1 IRQ line.
	 */
	uint32_t irq = (source / ESP32C3_INTC_SRCS_PER_IRQ);

	if (irq > ESP32C3_INTC_AVAILABLE_IRQS) {
		INTC_LOG("Clamping the source: %d no more IRQs available", source);
		irq = ESP32C3_INTC_AVAILABLE_IRQS;
	} else if (irq == 0) {
		irq = 1;
	}

	INTC_LOG("Found IRQ: %d for source: %d", irq, source);

	return irq;
}

void esp_intr_initialize(void)
{
	/* IRQ 31 is reserved for disabled interrupts,
	 * so route all sources to it
	 */
	for (int i = 0 ; i < ESP32C3_INTC_AVAILABLE_IRQS + 2; i++) {
		irq_disable(i);
	}

	for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) {
		esp_rom_intr_matrix_set(0, i, ESP32C3_INTC_DISABLED_SLOT);
	}

	/* set global esp32c3's INTC masking level */
	esprv_intc_int_set_threshold(ESP32C3_INTC_DEFAULT_THRESHOLD);
}

int esp_intr_alloc(int source,
		int flags,
		isr_handler_t handler,
		void *arg,
		void **ret_handle)
{
	ARG_UNUSED(flags);
	ARG_UNUSED(ret_handle);

	if (handler == NULL) {
		return -EINVAL;
	}

	if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
		return -EINVAL;
	}

	uint32_t key = irq_lock();

	irq_connect_dynamic(source,
		ESP32C3_INTC_DEFAULT_PRIORITY,
		handler,
		arg,
		0);

	if (source < 32) {
		esp_intr_enabled_mask[0] |= (1 << source);
	} else {
		esp_intr_enabled_mask[1] |= (1 << (source - 32));
	}

	INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X",
		esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);

	irq_unlock(key);
	irq_enable(source);

	return 0;
}

int esp_intr_disable(int source)
{
	if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
		return -EINVAL;
	}

	uint32_t key = irq_lock();

	esp_rom_intr_matrix_set(0,
		source,
		ESP32C3_INTC_DISABLED_SLOT);

	if (source < 32) {
		esp_intr_enabled_mask[0] &= ~(1 << source);
	} else {
		esp_intr_enabled_mask[1] &= ~(1 << (source - 32));
	}

	INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X",
		esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);

	irq_unlock(key);

	return 0;
}

int esp_intr_enable(int source)
{
	if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
		return -EINVAL;
	}

	uint32_t key = irq_lock();
	uint32_t irq = esp_intr_find_irq_for_source(source);

	esp_rom_intr_matrix_set(0, source, irq);

	if (source < 32) {
		esp_intr_enabled_mask[0] |= (1 << source);
	} else {
		esp_intr_enabled_mask[1] |= (1 << (source - 32));
	}

	INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X",
		esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);

	esprv_intc_int_set_priority(irq, ESP32C3_INTC_DEFAULT_PRIO);
	esprv_intc_int_set_type(irq, INTR_TYPE_LEVEL);
	esprv_intc_int_enable(1 << irq);

	irq_unlock(key);

	return 0;
}

uint32_t esp_intr_get_enabled_intmask(int status_mask_number)
{
	INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X",
		esp_intr_enabled_mask[0], esp_intr_enabled_mask[1]);

	if (status_mask_number == 0) {
		return esp_intr_enabled_mask[0];
	} else {
		return esp_intr_enabled_mask[1];
	}
}
