/*
 * Copyright (c) 2016 Piotr Mienkowski
 * SPDX-License-Identifier: Apache-2.0
 */

/** @file
 * @brief Atmel SAM MCU family General Purpose Input Output (GPIO)
 * module HAL driver.
 */

#include <misc/__assert.h>
#include "soc_gpio.h"

/*
 * There exist minor differences between SAM MCU family members in naming
 * of some of the registers. Check that our expectations are met.
 */
#if (!defined(PIO_IFSCER_P0) && !defined(PIO_DIFSR_P0)) \
	|| (!defined(PIO_IFSCDR_P0) && !defined(PIO_SCIFSR_P0)) \
	|| (!defined(PIO_ABCDSR_P0) && !defined(PIO_ABSR_P0))
#error "Unsupported Atmel SAM MCU series"
#endif

static void configure_common_attr(Pio *pio, u32_t mask, u32_t flags)
{
	/* Disable interrupts on the pin(s) */
	pio->PIO_IDR = mask;

	/* Configure pull-up(s) */
	if (flags & SOC_GPIO_PULLUP) {
		pio->PIO_PUER = mask;
	} else {
		pio->PIO_PUDR = mask;
	}

/* Configure pull-down only for MCU series that support it */
#if defined PIO_PPDER_P0
	/* Configure pull-down(s) */
	if (flags & SOC_GPIO_PULLDOWN) {
		pio->PIO_PPDER = mask;
	} else {
		pio->PIO_PPDDR = mask;
	}
#endif

	/* Configure open drain (multi-drive) */
	if (flags & SOC_GPIO_OPENDRAIN) {
		pio->PIO_MDER = mask;
	} else {
		pio->PIO_MDDR = mask;
	}
}

static void configure_input_attr(Pio *pio, u32_t mask, u32_t flags)
{
	/* Configure input filter */
	if ((flags & SOC_GPIO_IN_FILTER_MASK) != 0) {
		if ((flags & SOC_GPIO_IN_FILTER_MASK) == SOC_GPIO_IN_FILTER_DEBOUNCE) {
			/* Enable de-bounce, disable de-glitch */
#if defined PIO_IFSCER_P0
			pio->PIO_IFSCER = mask;
#elif defined PIO_DIFSR_P0
			pio->PIO_DIFSR = mask;
#endif
		} else {
			/* Disable de-bounce, enable de-glitch */
#if defined PIO_IFSCDR_P0
			pio->PIO_IFSCDR = mask;
#elif defined PIO_SCIFSR_P0
			pio->PIO_SCIFSR = mask;
#endif
		}
		pio->PIO_IFER = mask;
	} else {
		pio->PIO_IFDR = mask;
	}

	/* Configure interrupt */
	if (flags & SOC_GPIO_INT_ENABLE) {
		if ((flags & SOC_GPIO_INT_TRIG_MASK) == SOC_GPIO_INT_TRIG_DOUBLE_EDGE) {
			/* Disable additional interrupt modes, enable the default */
			pio->PIO_AIMDR = mask;
		} else {
			/* Configure additional interrupt mode */
			if ((flags & SOC_GPIO_INT_TRIG_MASK) == SOC_GPIO_INT_TRIG_EDGE) {
				/* Select edge detection event */
				pio->PIO_ESR = mask;
			} else {
				/* Select level detection event */
				pio->PIO_LSR = mask;
			}

			if (flags & SOC_GPIO_INT_ACTIVE_HIGH) {
				pio->PIO_REHLSR = mask;
			} else {
				pio->PIO_FELLSR = mask;
			}
			/* Enable additional interrupt mode */
			pio->PIO_AIMER = mask;
		}
		/* Enable interrupts on the pin(s) */
		pio->PIO_IER = mask;
	} else {
		/* Nothing to do. All interrupts were disabled in the
		 * beginning.
		 */
	}
}

static void configure_output_attr(Pio *pio, u32_t mask, u32_t flags)
{
	/* Enable control of the I/O line by the PIO_ODSR register */
	pio->PIO_OWER = mask;
}

void soc_gpio_configure(const struct soc_gpio_pin *pin)
{
	u32_t mask = pin->mask;
	Pio *pio = pin->regs;
	u8_t periph_id = pin->periph_id;
	u32_t flags = pin->flags;
	u32_t type = pin->flags & SOC_GPIO_FUNC_MASK;

	/* Configure pin attributes common to all functions */
	configure_common_attr(pio, mask, flags);

	switch (type) {
	case SOC_GPIO_FUNC_A:
#if defined PIO_ABCDSR_P0
		pio->PIO_ABCDSR[0] &= ~mask;
		pio->PIO_ABCDSR[1] &= ~mask;
#elif defined PIO_ABSR_P0
		pio->PIO_ABSR &= ~mask;
#endif
		/* Connect pin to the peripheral (disconnect PIO block) */
		pio->PIO_PDR = mask;
		break;

	case SOC_GPIO_FUNC_B:
#if defined PIO_ABCDSR_P0
		pio->PIO_ABCDSR[0] |= mask;
		pio->PIO_ABCDSR[1] &= ~mask;
#elif defined PIO_ABSR_P0
		pio->PIO_ABSR |= mask;
#endif
		/* Connect pin to the peripheral (disconnect PIO block) */
		pio->PIO_PDR = mask;
		break;

#if defined PIO_ABCDSR_P0
	case SOC_GPIO_FUNC_C:
		pio->PIO_ABCDSR[0] &= ~mask;
		pio->PIO_ABCDSR[1] |= mask;
		/* Connect pin to the peripheral (disconnect PIO block) */
		pio->PIO_PDR = mask;
		break;

	case SOC_GPIO_FUNC_D:
		pio->PIO_ABCDSR[0] |= mask;
		pio->PIO_ABCDSR[1] |= mask;
		/* Connect pin to the peripheral (disconnect PIO block) */
		pio->PIO_PDR = mask;
		break;
#endif

	case SOC_GPIO_FUNC_IN:
		/* Enable module's clock */
		soc_pmc_peripheral_enable(periph_id);
		/* Configure pin attributes related to input function */
		configure_input_attr(pio, mask, flags);
		/* Configure pin as input */
		pio->PIO_ODR = mask;
		pio->PIO_PER = mask;
		break;

	case SOC_GPIO_FUNC_OUT_1:
	case SOC_GPIO_FUNC_OUT_0:
		/* Set initial pin value */
		if (type == SOC_GPIO_FUNC_OUT_1) {
			pio->PIO_SODR = mask;
		} else {
			pio->PIO_CODR = mask;
		}

		/* Configure pin attributes related to output function */
		configure_output_attr(pio, mask, flags);
		/* Configure pin(s) as output(s) */
		pio->PIO_OER = mask;
		pio->PIO_PER = mask;
		break;

	default:
		__ASSERT(0, "Unsupported pin function, check pin.flags value");
		return;
	}
}

void soc_gpio_list_configure(const struct soc_gpio_pin pins[],
			     unsigned int size)
{
	for (int i = 0; i < size; i++) {
		soc_gpio_configure(&pins[i]);
	}
}
