/*
 * Copyright (c) 2017, Texas Instruments Incorporated
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#include <zephyr.h>
#include <misc/__assert.h>
#include <kernel/zephyr/dpl/dpl.h>
#include <ti/drivers/dpl/HwiP.h>

#include <inc/hw_types.h>
#include <inc/hw_ints.h>
#include <driverlib/rom.h>
#include <driverlib/rom_map.h>
#include <driverlib/interrupt.h>

/*
 * IRQ_CONNECT requires we know the ISR signature and argument
 * at build time; whereas SimpleLink plugs the interrupts
 * at run time, so we create an ISR shim, and register that.
 * The callback argument doesn't change after the ISR is registered.
 */
struct sl_isr_args
{
	HwiP_Fxn cb;
	uintptr_t arg;
};

static struct sl_isr_args sl_UDMA_cb = {NULL, 0};
static struct sl_isr_args sl_UDMAERR_cb = {NULL, 0};
static struct sl_isr_args sl_NWPIC_cb = {NULL, 0};
static struct sl_isr_args sl_LSPI_cb = {NULL, 0};

static void sl_isr(void *isr_arg)
{
	HwiP_Fxn cb = ((struct sl_isr_args *)isr_arg)->cb;
	uintptr_t arg =	 ((struct sl_isr_args *)isr_arg)->arg;

	/* Call the SimpleLink ISR Handler: */
	if (cb) {
		cb(arg);
	}
}

/* Must hardcode the IRQ for IRQ_CONNECT macro.	 Must be <= CONFIG_NUM_IRQs.*/
#define EXCEPTION_UDMA		46	/* == INT_UDMA	(62) - 16 */
#define EXCEPTION_UDMAERR	47	/* == INT_UDMAERR (63) - 16 */
#define EXCEPTION_NWPIC		171	/* == INT_NWPIC (187) - 16 */
#define EXCEPTION_LSPI		177	/* == INT_LSPI (193) - 16 */

HwiP_Handle HwiP_create(int interruptNum, HwiP_Fxn hwiFxn, HwiP_Params *params)
{
	HwiP_Handle handle = 0;
	uint32_t priority = ~0;
	uintptr_t arg = 0;

	if (params) {
		priority = params->priority;
		arg = params->arg;
	}

	/*
	 * SimpleLink only uses the NWPIC, UDMA, UDMAERR and LSPI interrupts:
	 */
	__ASSERT(INT_NWPIC == interruptNum || INT_UDMA == interruptNum ||
		 INT_UDMAERR == interruptNum || INT_LSPI == interruptNum,
		 "Unexpected interruptNum: %d\r\n",
		 interruptNum);
	/*
	 * Priority expected is either:
	 *    INT_PRIORITY_LVL_1,
	 *    or ~0 or 255 (meaning lowest priority)
	 *    ~0 and 255 are meant to be the same as INT_PRIORITY_LVL_7.
	 *    For ~0 or 255, we want 7; but Zephyr IRQ_CONNECT adds +1,
	 *    so we pass 6 for those TI drivers passing prio = ~0.
	 */
	__ASSERT((INT_PRIORITY_LVL_1 == priority) ||
		 (0xff == (priority & 0xff)),
		 "Expected priority: 0x%x or 0x%x, got: 0x%x\r\n",
		 INT_PRIORITY_LVL_1, 0xff, (unsigned int)priority);

	switch(interruptNum) {
	case INT_UDMA:
		sl_UDMA_cb.cb = hwiFxn;
		sl_UDMA_cb.arg = arg;
		IRQ_CONNECT(EXCEPTION_UDMA, 6, sl_isr, &sl_UDMA_cb, 0);
		break;
	case INT_UDMAERR:
		sl_UDMAERR_cb.cb = hwiFxn;
		sl_UDMAERR_cb.arg = arg;
		IRQ_CONNECT(EXCEPTION_UDMAERR, 6, sl_isr, &sl_UDMAERR_cb, 0);
		break;
	case INT_NWPIC:
		sl_NWPIC_cb.cb = hwiFxn;
		sl_NWPIC_cb.arg = arg;
		IRQ_CONNECT(EXCEPTION_NWPIC, 1, sl_isr, &sl_NWPIC_cb, 0);
		break;
	case INT_LSPI:
		sl_LSPI_cb.cb = hwiFxn;
		sl_LSPI_cb.arg = arg;
		IRQ_CONNECT(EXCEPTION_LSPI, 6, sl_isr, &sl_LSPI_cb, 0);
		break;
	default:
		return(handle);
	}
	irq_enable(interruptNum - 16);

	return (HwiP_Handle)interruptNum;
}

/* Can't actually de-register an interrupt in Zephyr, so just disable: */
void HwiP_delete(HwiP_Handle handle)
{
	int interruptNum = (int)handle;

	__ASSERT(INT_NWPIC == interruptNum || INT_UDMA == interruptNum ||
		 INT_UDMAERR == interruptNum || INT_LSPI == interruptNum,
		 "Unexpected interruptNum: %d\r\n",
		 interruptNum);

	irq_disable(interruptNum - 16);
}

void HwiP_Params_init(HwiP_Params *params)
{
	params->arg = 0;
	params->priority = ~0;
}

/* Zephyr has no functions for clearing an interrupt, so use driverlib: */
void HwiP_clearInterrupt(int interruptNum)
{
	MAP_IntPendClear((unsigned long)interruptNum);
}

void HwiP_enableInterrupt(int interruptNum)
{
	irq_enable(interruptNum - 16);
}

void HwiP_disableInterrupt(int interruptNum)
{
	irq_disable(interruptNum - 16);
}

uintptr_t HwiP_disable(void)
{
	uintptr_t key;

	key = irq_lock();

	return (key);
}

void HwiP_restore(uintptr_t key)
{
	irq_unlock(key);
}
