// 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 <log.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, 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_sc = !dm_i2c_probe(i2c_bus, MC2_EXPANDER_ADDR, 0, &dummy);
	mc4 = !dm_i2c_probe(i2c_bus, MC4_EXPANDER_ADDR, 0, &dummy);

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

	listname = mc2_sc ? "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;
	}

	mc2 = mc2_sc ? (sc ? 0 : 1) : 0;

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

	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;
	}

	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,
};
