/*
 * Copyright (c) 2011 The Chromium OS Authors.
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <asm/gpio.h>

/* Flags for each GPIO */
#define GPIOF_OUTPUT	(1 << 0)	/* Currently set as an output */
#define GPIOF_HIGH	(1 << 1)	/* Currently set high */
#define GPIOF_RESERVED	(1 << 2)	/* Is in use / requested */

struct gpio_state {
	const char *label;	/* label given by requester */
	u8 flags;		/* flags (GPIOF_...) */
};

/*
 * State of GPIOs
 * TODO: Put this into sandbox state
 */
static struct gpio_state state[CONFIG_SANDBOX_GPIO_COUNT];

/* Access routines for GPIO state */
static u8 *get_gpio_flags(unsigned gp)
{
	/* assert()'s could be disabled, so make sure we handle that */
	assert(gp < ARRAY_SIZE(state));
	if (gp >= ARRAY_SIZE(state)) {
		static u8 invalid_flags;
		printf("sandbox_gpio: error: invalid gpio %u\n", gp);
		return &invalid_flags;
	}

	return &state[gp].flags;
}

static int get_gpio_flag(unsigned gp, int flag)
{
	return (*get_gpio_flags(gp) & flag) != 0;
}

static int set_gpio_flag(unsigned gp, int flag, int value)
{
	u8 *gpio = get_gpio_flags(gp);

	if (value)
		*gpio |= flag;
	else
		*gpio &= ~flag;

	return 0;
}

static int check_reserved(unsigned gpio, const char *func)
{
	if (!get_gpio_flag(gpio, GPIOF_RESERVED)) {
		printf("sandbox_gpio: %s: error: gpio %u not reserved\n",
			func, gpio);
		return -1;
	}

	return 0;
}

/*
 * Back-channel sandbox-internal-only access to GPIO state
 */

int sandbox_gpio_get_value(unsigned gp)
{
	if (get_gpio_flag(gp, GPIOF_OUTPUT))
		debug("sandbox_gpio: get_value on output gpio %u\n", gp);
	return get_gpio_flag(gp, GPIOF_HIGH);
}

int sandbox_gpio_set_value(unsigned gp, int value)
{
	return set_gpio_flag(gp, GPIOF_HIGH, value);
}

int sandbox_gpio_get_direction(unsigned gp)
{
	return get_gpio_flag(gp, GPIOF_OUTPUT);
}

int sandbox_gpio_set_direction(unsigned gp, int output)
{
	return set_gpio_flag(gp, GPIOF_OUTPUT, output);
}

/*
 * These functions implement the public interface within U-Boot
 */

/* set GPIO port 'gp' as an input */
int gpio_direction_input(unsigned gp)
{
	debug("%s: gp:%u\n", __func__, gp);

	if (check_reserved(gp, __func__))
		return -1;

	return sandbox_gpio_set_direction(gp, 0);
}

/* set GPIO port 'gp' as an output, with polarity 'value' */
int gpio_direction_output(unsigned gp, int value)
{
	debug("%s: gp:%u, value = %d\n", __func__, gp, value);

	if (check_reserved(gp, __func__))
		return -1;

	return sandbox_gpio_set_direction(gp, 1) |
		sandbox_gpio_set_value(gp, value);
}

/* read GPIO IN value of port 'gp' */
int gpio_get_value(unsigned gp)
{
	debug("%s: gp:%u\n", __func__, gp);

	if (check_reserved(gp, __func__))
		return -1;

	return sandbox_gpio_get_value(gp);
}

/* write GPIO OUT value to port 'gp' */
int gpio_set_value(unsigned gp, int value)
{
	debug("%s: gp:%u, value = %d\n", __func__, gp, value);

	if (check_reserved(gp, __func__))
		return -1;

	if (!sandbox_gpio_get_direction(gp)) {
		printf("sandbox_gpio: error: set_value on input gpio %u\n", gp);
		return -1;
	}

	return sandbox_gpio_set_value(gp, value);
}

int gpio_request(unsigned gp, const char *label)
{
	debug("%s: gp:%u, label:%s\n", __func__, gp, label);

	if (gp >= ARRAY_SIZE(state)) {
		printf("sandbox_gpio: error: invalid gpio %u\n", gp);
		return -1;
	}

	if (get_gpio_flag(gp, GPIOF_RESERVED)) {
		printf("sandbox_gpio: error: gpio %u already reserved\n", gp);
		return -1;
	}

	state[gp].label = label;
	return set_gpio_flag(gp, GPIOF_RESERVED, 1);
}

int gpio_free(unsigned gp)
{
	debug("%s: gp:%u\n", __func__, gp);

	if (check_reserved(gp, __func__))
		return -1;

	state[gp].label = NULL;
	return set_gpio_flag(gp, GPIOF_RESERVED, 0);
}

/* Display GPIO information */
void gpio_info(void)
{
	unsigned gpio;

	puts("Sandbox GPIOs\n");

	for (gpio = 0; gpio < ARRAY_SIZE(state); ++gpio) {
		const char *label = state[gpio].label;

		printf("%4d: %s: %d [%c] %s\n",
			gpio,
			sandbox_gpio_get_direction(gpio) ? "out" : " in",
			sandbox_gpio_get_value(gpio),
			get_gpio_flag(gpio, GPIOF_RESERVED) ? 'x' : ' ',
			label ? label : "");
	}
}
