// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2019
 * Alex Marginean, NXP
 */

#include <common.h>
#include <dm.h>
#include <miiphy.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#include <dm/lists.h>

#define MDIO_MUX_CHILD_DRV_NAME	"mdio-mux-bus-drv"

/**
 * struct mdio_mux_perdev_priv - Per-device class data for MDIO MUX DM
 *
 * @parent_mdio: Parent DM MDIO device, this is called for actual MDIO I/O after
 *               setting up the mux.  Typically this is a real MDIO device,
 *               unless there are cascaded muxes.
 * @selected:    Current child bus selection.  Defaults to -1
 */
struct mdio_mux_perdev_priv {
	struct udevice *mdio_parent;
	int selected;
};

/*
 * This source file uses three types of devices, as follows:
 * - mux is the hardware MDIO MUX which selects between the existing child MDIO
 * buses, this is the device relevant for MDIO MUX class of drivers.
 * - ch is a child MDIO bus, this is just a representation of a mux selection,
 * not a real piece of hardware.
 * - mdio_parent is the actual MDIO bus called to perform reads/writes after
 * the MUX is configured.  Typically this is a real MDIO device, unless there
 * are cascaded muxes.
 */

/**
 * struct mdio_mux_ch_data - Per-device data for child MDIOs
 *
 * @sel: Selection value used by the MDIO MUX to access this child MDIO bus
 */
struct mdio_mux_ch_data {
	int sel;
};

static struct udevice *mmux_get_parent_mdio(struct udevice *mux)
{
	struct mdio_mux_perdev_priv *pdata = dev_get_uclass_priv(mux);

	return pdata->mdio_parent;
}

static struct mdio_ops *mmux_get_mdio_parent_ops(struct udevice *mux)
{
	return mdio_get_ops(mmux_get_parent_mdio(mux));
}

/* call driver select function before performing MDIO r/w */
static int mmux_change_sel(struct udevice *ch, bool sel)
{
	struct udevice *mux = ch->parent;
	struct mdio_mux_perdev_priv *priv = dev_get_uclass_priv(mux);
	struct mdio_mux_ops *ops = mdio_mux_get_ops(mux);
	struct mdio_mux_ch_data *ch_data = dev_get_parent_platdata(ch);
	int err = 0;

	if (sel) {
		err = ops->select(mux, priv->selected, ch_data->sel);
		if (err)
			return err;

		priv->selected = ch_data->sel;
	} else {
		if (ops->deselect) {
			ops->deselect(mux, ch_data->sel);
			priv->selected = MDIO_MUX_SELECT_NONE;
		}
	}

	return 0;
}

/* Read wrapper, sets up the mux before issuing a read on parent MDIO bus */
static int mmux_read(struct udevice *ch, int addr, int devad,
		     int reg)
{
	struct udevice *mux = ch->parent;
	struct udevice *parent_mdio = mmux_get_parent_mdio(mux);
	struct mdio_ops *parent_ops = mmux_get_mdio_parent_ops(mux);
	int err;

	err = mmux_change_sel(ch, true);
	if (err)
		return err;

	err = parent_ops->read(parent_mdio, addr, devad, reg);
	mmux_change_sel(ch, false);

	return err;
}

/* Write wrapper, sets up the mux before issuing a write on parent MDIO bus */
static int mmux_write(struct udevice *ch, int addr, int devad,
		      int reg, u16 val)
{
	struct udevice *mux = ch->parent;
	struct udevice *parent_mdio = mmux_get_parent_mdio(mux);
	struct mdio_ops *parent_ops = mmux_get_mdio_parent_ops(mux);
	int err;

	err = mmux_change_sel(ch, true);
	if (err)
		return err;

	err = parent_ops->write(parent_mdio, addr, devad, reg, val);
	mmux_change_sel(ch, false);

	return err;
}

/* Reset wrapper, sets up the mux before issuing a reset on parent MDIO bus */
static int mmux_reset(struct udevice *ch)
{
	struct udevice *mux = ch->parent;
	struct udevice *parent_mdio = mmux_get_parent_mdio(mux);
	struct mdio_ops *parent_ops = mmux_get_mdio_parent_ops(mux);
	int err;

	/* reset is optional, if it's not implemented just exit */
	if (!parent_ops->reset)
		return 0;

	err = mmux_change_sel(ch, true);
	if (err)
		return err;

	err = parent_ops->reset(parent_mdio);
	mmux_change_sel(ch, false);

	return err;
}

/* Picks up the mux selection value for each child */
static int dm_mdio_mux_child_post_bind(struct udevice *ch)
{
	struct mdio_mux_ch_data *ch_data = dev_get_parent_platdata(ch);

	ch_data->sel = dev_read_u32_default(ch, "reg", MDIO_MUX_SELECT_NONE);

	if (ch_data->sel == MDIO_MUX_SELECT_NONE)
		return -EINVAL;

	return 0;
}

/* Explicitly bind child MDIOs after binding the mux */
static int dm_mdio_mux_post_bind(struct udevice *mux)
{
	ofnode ch_node;
	int err, first_err = 0;

	if (!ofnode_valid(mux->node)) {
		debug("%s: no mux node found, no child MDIO busses set up\n",
		      __func__);
		return 0;
	}

	/*
	 * we're going by Linux bindings so the child nodes do not have
	 * compatible strings.  We're going through them here and binding to
	 * them.
	 */
	dev_for_each_subnode(ch_node, mux) {
		struct udevice *ch_dev;
		const char *ch_name;

		ch_name = ofnode_get_name(ch_node);

		err = device_bind_driver_to_node(mux, MDIO_MUX_CHILD_DRV_NAME,
						 ch_name, ch_node, &ch_dev);
		/* try to bind all, but keep 1st error */
		if (err && !first_err)
			first_err = err;
	}

	return first_err;
}

/* Get a reference to the parent MDIO bus, it should be bound by now */
static int dm_mdio_mux_post_probe(struct udevice *mux)
{
	struct mdio_mux_perdev_priv *priv = dev_get_uclass_priv(mux);
	int err;

	priv->selected = MDIO_MUX_SELECT_NONE;

	/* pick up mdio parent from device tree */
	err = uclass_get_device_by_phandle(UCLASS_MDIO, mux, "mdio-parent-bus",
					   &priv->mdio_parent);
	if (err) {
		debug("%s: didn't find mdio-parent-bus\n", __func__);
		return err;
	}

	return 0;
}

const struct mdio_ops mmux_child_mdio_ops = {
	.read = mmux_read,
	.write = mmux_write,
	.reset = mmux_reset,
};

/* MDIO class driver used for MUX child MDIO buses */
U_BOOT_DRIVER(mdio_mux_child) = {
	.name		= MDIO_MUX_CHILD_DRV_NAME,
	.id		= UCLASS_MDIO,
	.ops		= &mmux_child_mdio_ops,
};

UCLASS_DRIVER(mdio_mux) = {
	.id = UCLASS_MDIO_MUX,
	.name = "mdio-mux",
	.child_post_bind = dm_mdio_mux_child_post_bind,
	.post_bind  = dm_mdio_mux_post_bind,
	.post_probe = dm_mdio_mux_post_probe,
	.per_device_auto_alloc_size = sizeof(struct mdio_mux_perdev_priv),
	.per_child_platdata_auto_alloc_size = sizeof(struct mdio_mux_ch_data),
};
