// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2017
 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
 */

#include <common.h>
#include <dm.h>
#include <board.h>
#include <i2c.h>
#include <asm/gpio.h>

#include "gazerbeam.h"

/* Sequence number of I2C bus that holds the GPIO expanders */
static const int I2C_BUS_SEQ_NO = 1;

/* I2C address of SC/MC2 expander */
static const int MC2_EXPANDER_ADDR = 0x20;
/* I2C address of MC4 expander */
static const int MC4_EXPANDER_ADDR = 0x22;

/* Number of the GPIO to read the SC data from */
static const int SC_GPIO_NO;
/* Number of the GPIO to read the CON data from */
static const int CON_GPIO_NO = 1;

/**
 * struct board_gazerbeam_priv - Private data structure for the gazerbeam board
 *				 driver.
 * @reset_gpios:  GPIOs for the board's reset GPIOs.
 * @var_gpios:	  GPIOs for the board's hardware variant GPIOs
 * @ver_gpios:	  GPIOs for the board's hardware version GPIOs
 * @variant:	  Container for the board's hardware variant (CON/CPU)
 * @multichannel: Container for the board's multichannel variant (MC4/MC2/SC)
 * @hwversion:	  Container for the board's hardware version
 */
struct board_gazerbeam_priv {
	struct gpio_desc reset_gpios[2];
	struct gpio_desc var_gpios[2];
	struct gpio_desc ver_gpios[4];
	int variant;
	int multichannel;
	int hwversion;
};

/**
 * _read_board_variant_data() - Read variant information from the hardware.
 * @dev: The board device for which to determine the multichannel and device
 *	 type information.
 *
 * The data read from the board's hardware (mostly hard-wired GPIOs) is stored
 * in the private data structure of the driver to be used by other driver
 * methods.
 *
 * Return: 0 if OK, -ve on error.
 */
static int _read_board_variant_data(struct udevice *dev)
{
	struct board_gazerbeam_priv *priv = dev_get_priv(dev);
	struct udevice *i2c_bus;
	struct udevice *dummy;
	char *listname;
	int mc4, mc2, sc, con;
	int gpio_num;
	int res;

	res = uclass_get_device_by_seq(UCLASS_I2C, I2C_BUS_SEQ_NO, &i2c_bus);
	if (res) {
		debug("%s: Could not get I2C bus %d (err = %d)\n",
		      dev->name, I2C_BUS_SEQ_NO, res);
		return res;
	}

	if (!i2c_bus) {
		debug("%s: Could not get I2C bus %d\n",
		      dev->name, I2C_BUS_SEQ_NO);
		return -EIO;
	}

	mc2 = !dm_i2c_probe(i2c_bus, MC2_EXPANDER_ADDR, 0, &dummy);
	mc4 = !dm_i2c_probe(i2c_bus, MC4_EXPANDER_ADDR, 0, &dummy);

	if (mc2 && mc4) {
		debug("%s: Board hardware configuration inconsistent.\n",
		      dev->name);
		return -EINVAL;
	}

	listname = mc2 ? "var-gpios-mc2" : "var-gpios-mc4";

	gpio_num = gpio_request_list_by_name(dev, listname, priv->var_gpios,
					     ARRAY_SIZE(priv->var_gpios),
					     GPIOD_IS_IN);
	if (gpio_num < 0) {
		debug("%s: Requesting gpio list %s failed (err = %d).\n",
		      dev->name, listname, gpio_num);
		return gpio_num;
	}

	sc = dm_gpio_get_value(&priv->var_gpios[SC_GPIO_NO]);
	if (sc < 0) {
		debug("%s: Error while reading 'sc' GPIO (err = %d)",
		      dev->name, sc);
		return sc;
	}

	con = dm_gpio_get_value(&priv->var_gpios[CON_GPIO_NO]);
	if (con < 0) {
		debug("%s: Error while reading 'con' GPIO (err = %d)",
		      dev->name, con);
		return con;
	}

	if ((sc && mc2) || (sc && mc4) || (!sc && !mc2 && !mc4)) {
		debug("%s: Board hardware configuration inconsistent.\n",
		      dev->name);
		return -EINVAL;
	}

	priv->variant = con ? VAR_CON : VAR_CPU;

	priv->multichannel = mc4 ? 4 : (mc2 ? 2 : (sc ? 1 : 0));

	return 0;
}

/**
 * _read_hwversion() - Read the hardware version from the board.
 * @dev: The board device for which to read the hardware version.
 *
 * The hardware version read from the board (from hard-wired GPIOs) is stored
 * in the private data structure of the driver to be used by other driver
 * methods.
 *
 * Return: 0 if OK, -ve on error.
 */
static int _read_hwversion(struct udevice *dev)
{
	struct board_gazerbeam_priv *priv = dev_get_priv(dev);
	int res;

	res = gpio_request_list_by_name(dev, "ver-gpios", priv->ver_gpios,
					ARRAY_SIZE(priv->ver_gpios),
					GPIOD_IS_IN);
	if (res < 0) {
		debug("%s: Error getting GPIO list 'ver-gpios' (err = %d)\n",
		      dev->name, res);
		return -ENODEV;
	}

	res = dm_gpio_get_values_as_int(priv->ver_gpios,
					ARRAY_SIZE(priv->ver_gpios));
	if (res < 0) {
		debug("%s: Error reading HW version from expander (err = %d)\n",
		      dev->name, res);
		return res;
	}

	priv->hwversion = res;

	res = gpio_free_list(dev, priv->ver_gpios, ARRAY_SIZE(priv->ver_gpios));
	if (res < 0) {
		debug("%s: Error freeing HW version GPIO list (err = %d)\n",
		      dev->name, res);
		return res;
	}

	return 0;
}

static int board_gazerbeam_detect(struct udevice *dev)
{
	int res;

	res = _read_board_variant_data(dev);
	if (res) {
		debug("%s: Error reading multichannel variant (err = %d)\n",
		      dev->name, res);
		return res;
	}

	res = _read_hwversion(dev);
	if (res) {
		debug("%s: Error reading hardware version (err = %d)\n",
		      dev->name, res);
		return res;
	}

	return 0;
}

static int board_gazerbeam_get_int(struct udevice *dev, int id, int *val)
{
	struct board_gazerbeam_priv *priv = dev_get_priv(dev);

	switch (id) {
	case BOARD_MULTICHANNEL:
		*val = priv->multichannel;
		break;
	case BOARD_VARIANT:
		*val = priv->variant;
		break;
	case BOARD_HWVERSION:
		*val = priv->hwversion;
		break;
	default:
		debug("%s: Integer value %d unknown\n", dev->name, id);
		return -EINVAL;
	}

	return 0;
}

static const struct udevice_id board_gazerbeam_ids[] = {
	{ .compatible = "gdsys,board_gazerbeam" },
	{ /* sentinel */ }
};

static const struct board_ops board_gazerbeam_ops = {
	.detect = board_gazerbeam_detect,
	.get_int = board_gazerbeam_get_int,
};

static int board_gazerbeam_probe(struct udevice *dev)
{
	struct board_gazerbeam_priv *priv = dev_get_priv(dev);
	int gpio_num, i;

	gpio_num = gpio_request_list_by_name(dev, "reset-gpios",
					     priv->reset_gpios,
					     ARRAY_SIZE(priv->reset_gpios),
					     GPIOD_IS_OUT);

	if (gpio_num < 0) {
		debug("%s: Error getting GPIO list 'reset-gpios' (err = %d)\n",
		      dev->name, gpio_num);
		return gpio_num;
	}

	/* Set startup-finished GPIOs */
	for (i = 0; i < ARRAY_SIZE(priv->reset_gpios); i++) {
		int res = dm_gpio_set_value(&priv->reset_gpios[i], 0);

		if (res) {
			debug("%s: Error while setting GPIO %d (err = %d)\n",
			      dev->name, i, res);
			return res;
		}
	}

	return 0;
}

U_BOOT_DRIVER(board_gazerbeam) = {
	.name           = "board_gazerbeam",
	.id             = UCLASS_BOARD,
	.of_match       = board_gazerbeam_ids,
	.ops		= &board_gazerbeam_ops,
	.priv_auto_alloc_size = sizeof(struct board_gazerbeam_priv),
	.probe          = board_gazerbeam_probe,
};
