/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>

#include <board.h>
#include <soc.h>
#include <drivers/gpio.h>

#include <sys/printk.h>
#include <sys/util.h>

/**
 * @file
 *
 * @brief Example of using GPIOs on UP Squared board
 *
 * This example outputs the value of a counter via 4 GPIO lines
 * as a 4-bit value (bin 0, 1, 2, 3 -> HAT Pin 35, 37, 38, 40).
 * The counter increments for each change from 0 to 1 on HAT Pin 16.
 *
 * Note:
 * Need to change the BIOS settings:
 * () Advanced -> HAT Configurations:
 *    - HD-Audio / I2S6 Selec -> Disabled
 *    - GPIO / PWM3 Selection -> GPIO
 *    - GPIO / I2S2 Selection -> GPIO
 *
 *    - GPIO 19 (Pin16) Confi -> Input
 *
 *    - GPIO 14 (Pin35) Confi -> Output
 *    - GPIO 15 (Pin37) Confi -> Output
 *    - GPIO 27 (Pin38) Confi -> Output
 *    - GPIO 28 (Pin40) Confi -> Output
 */

struct _pin {
	uint32_t		hat_num;
	uint32_t		pin;
	const char	*gpio_dev_name;
	const struct device *gpio_dev;
};

struct _pin counter_pins[] = {
	{
		.hat_num = 35,
		.pin = UP2_HAT_PIN_35,
		.gpio_dev_name = UP2_HAT_PIN_35_DEV,
	},
	{
		.hat_num = 37,
		.pin = UP2_HAT_PIN_37,
		.gpio_dev_name = UP2_HAT_PIN_37_DEV,
	},
	{
		.hat_num = 38,
		.pin = UP2_HAT_PIN_38,
		.gpio_dev_name = UP2_HAT_PIN_38_DEV,
	},
	{
		.hat_num = 40,
		.pin = UP2_HAT_PIN_40,
		.gpio_dev_name = UP2_HAT_PIN_40_DEV,
	},
};

struct _pin intr_pin = {
	.hat_num = 16,
	.pin = UP2_HAT_PIN_16,
	.gpio_dev_name = UP2_HAT_PIN_16_DEV,
};

static struct gpio_callback gpio_cb;

static volatile uint32_t counter;

K_SEM_DEFINE(counter_sem, 0, 1);

#define NUM_PINS	ARRAY_SIZE(counter_pins)
#define MASK		(BIT(NUM_PINS) - 1)

void button_cb(const struct device *gpiodev, struct gpio_callback *cb,
	       uint32_t pin)
{
	counter++;
	k_sem_give(&counter_sem);
}

int get_gpio_dev(struct _pin *pin)
{
	pin->gpio_dev = device_get_binding(pin->gpio_dev_name);
	if (!pin->gpio_dev) {
		printk("ERROR: cannot get device binding for %s\n",
		       pin->gpio_dev_name);
		return -1;
	}

	return 0;
}

void main(void)
{
	uint32_t val;
	int i, ret;

	for (i = 0; i < NUM_PINS; i++) {
		if (get_gpio_dev(&counter_pins[i]) != 0) {
			return;
		}
	}

	if (get_gpio_dev(&intr_pin) != 0) {
		return;
	}

	/* Set pins to output */
	for (i = 0; i < NUM_PINS; i++) {
		ret = gpio_pin_configure(counter_pins[i].gpio_dev,
					 counter_pins[i].pin,
					 GPIO_OUTPUT_LOW);
		if (ret) {
			printk("ERROR: cannot set HAT pin %d to OUT (%d)\n",
			       counter_pins[i].hat_num, ret);
			return;
		}
	}

	/* Setup input pin */
	ret = gpio_pin_configure(intr_pin.gpio_dev, intr_pin.pin,
				 GPIO_INPUT);
	if (ret) {
		printk("ERROR: cannot set HAT pin %d to IN (%d)\n",
			       intr_pin.hat_num, ret);
			return;
	}


	/* Callback uses pin_mask, so need bit shifting */
	gpio_init_callback(&gpio_cb, button_cb, (1 << intr_pin.pin));
	gpio_add_callback(intr_pin.gpio_dev, &gpio_cb);

	/* Setup input pin for interrupt */
	ret = gpio_pin_interrupt_configure(intr_pin.gpio_dev, intr_pin.pin,
					   GPIO_INT_EDGE_RISING);
	if (ret) {
		printk("ERROR: cannot config interrupt on HAT pin %d (%d)\n",
			       intr_pin.hat_num, ret);
			return;
	}

	/* main loop */
	val = 0U;
	while (1) {
		printk("counter: 0x%x\n", val);

		for (i = 0; i < NUM_PINS; i++) {
			ret = gpio_pin_set(counter_pins[i].gpio_dev,
					   counter_pins[i].pin,
					   (val & BIT(i)));
			if (ret) {
				printk("ERROR: cannot set HAT pin %d value (%d)\n",
				       counter_pins[i].hat_num, ret);
				return;
			}
		}

		k_sem_take(&counter_sem, K_FOREVER);
		val = counter & MASK;
	}
}
