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

#include <common.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <miiphy.h>
#include <dm/device-internal.h>
#include <dm/device_compat.h>
#include <dm/of_extra.h>
#include <dm/uclass-internal.h>
#include <linux/compat.h>

/* DT node properties for MAC-PHY interface */
#define PHY_MODE_STR_CNT	2
static const char *phy_mode_str[PHY_MODE_STR_CNT] = { "phy-mode",
						      "phy-connection-type" };
/* DT node properties that reference a PHY node */
#define PHY_HANDLE_STR_CNT	3
const char *phy_handle_str[PHY_HANDLE_STR_CNT] = { "phy-handle",
						   "phy",
						   "phy-device" };

void dm_mdio_probe_devices(void)
{
	struct udevice *it;
	struct uclass *uc;

	uclass_get(UCLASS_MDIO, &uc);
	uclass_foreach_dev(it, uc) {
		device_probe(it);
	}
}

static int dm_mdio_post_bind(struct udevice *dev)
{
	const char *dt_name;

	/* set a custom name for the MDIO device, if present in DT */
	if (dev_has_ofnode(dev)) {
		dt_name = dev_read_string(dev, "device-name");
		if (dt_name) {
			debug("renaming dev %s to %s\n", dev->name, dt_name);
			device_set_name(dev, dt_name);
		}
	}

	/*
	 * MDIO command doesn't like spaces in names, don't allow them to keep
	 * it happy
	 */
	if (strchr(dev->name, ' ')) {
		debug("\nError: MDIO device name \"%s\" has a space!\n",
		      dev->name);
		return -EINVAL;
	}

	return 0;
}

/*
 * Following read/write/reset functions are registered with legacy MII code.
 * These are called for PHY operations by upper layers and we further call the
 * DM MDIO driver functions.
 */
static int mdio_read(struct mii_dev *mii_bus, int addr, int devad, int reg)
{
	struct udevice *dev = mii_bus->priv;

	return mdio_get_ops(dev)->read(dev, addr, devad, reg);
}

static int mdio_write(struct mii_dev *mii_bus, int addr, int devad, int reg,
		      u16 val)
{
	struct udevice *dev = mii_bus->priv;

	return mdio_get_ops(dev)->write(dev, addr, devad, reg, val);
}

static int mdio_reset(struct mii_dev *mii_bus)
{
	struct udevice *dev = mii_bus->priv;

	if (mdio_get_ops(dev)->reset)
		return mdio_get_ops(dev)->reset(dev);
	else
		return 0;
}

static int dm_mdio_post_probe(struct udevice *dev)
{
	struct mdio_perdev_priv *pdata = dev_get_uclass_priv(dev);

	pdata->mii_bus = mdio_alloc();
	pdata->mii_bus->read = mdio_read;
	pdata->mii_bus->write = mdio_write;
	pdata->mii_bus->reset = mdio_reset;
	pdata->mii_bus->priv = dev;
	strncpy(pdata->mii_bus->name, dev->name, MDIO_NAME_LEN - 1);

	return mdio_register(pdata->mii_bus);
}

static int dm_mdio_pre_remove(struct udevice *dev)
{
	struct mdio_perdev_priv *pdata = dev_get_uclass_priv(dev);
	struct mdio_ops *ops = mdio_get_ops(dev);

	if (ops->reset)
		ops->reset(dev);
	mdio_unregister(pdata->mii_bus);
	mdio_free(pdata->mii_bus);

	return 0;
}

struct phy_device *dm_mdio_phy_connect(struct udevice *mdiodev, int phyaddr,
				       struct udevice *ethdev,
				       phy_interface_t interface)
{
	struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdiodev);

	if (device_probe(mdiodev))
		return NULL;

	return phy_connect(pdata->mii_bus, phyaddr, ethdev, interface);
}

static struct phy_device *dm_eth_connect_phy_handle(struct udevice *ethdev,
						    phy_interface_t interface)
{
	u32 phy_addr;
	struct udevice *mdiodev;
	struct phy_device *phy;
	struct ofnode_phandle_args phandle = {.node = ofnode_null()};
	ofnode phynode;
	int i;

	if (CONFIG_IS_ENABLED(PHY_FIXED) &&
	    ofnode_phy_is_fixed_link(dev_ofnode(ethdev), &phynode)) {
		phy = phy_connect(NULL, 0, ethdev, interface);
		phandle.node = phynode;
		goto out;
	}

	for (i = 0; i < PHY_HANDLE_STR_CNT; i++)
		if (!dev_read_phandle_with_args(ethdev, phy_handle_str[i], NULL,
						0, 0, &phandle))
			break;

	if (!ofnode_valid(phandle.node)) {
		dev_dbg(ethdev, "can't find PHY node\n");
		return NULL;
	}

	/*
	 * reading 'reg' directly should be fine.  This is a PHY node, the
	 * address is always size 1 and requires no translation
	 */
	if (ofnode_read_u32(phandle.node, "reg", &phy_addr)) {
		dev_dbg(ethdev, "missing reg property in phy node\n");
		return NULL;
	}

	if (uclass_get_device_by_ofnode(UCLASS_MDIO,
					ofnode_get_parent(phandle.node),
					&mdiodev)) {
		dev_dbg(ethdev, "can't find MDIO bus for node %s\n",
			ofnode_get_name(ofnode_get_parent(phandle.node)));
		return NULL;
	}

	phy = dm_mdio_phy_connect(mdiodev, phy_addr, ethdev, interface);

out:
	if (phy)
		phy->node = phandle.node;

	return phy;
}

/* Connect to a PHY linked in eth DT node */
struct phy_device *dm_eth_phy_connect(struct udevice *ethdev)
{
	const char *if_str;
	phy_interface_t interface;
	struct phy_device *phy;
	int i;

	if (!dev_has_ofnode(ethdev)) {
		debug("%s: supplied eth dev has no DT node!\n", ethdev->name);
		return NULL;
	}

	interface = PHY_INTERFACE_MODE_NONE;
	for (i = 0; i < PHY_MODE_STR_CNT; i++) {
		if_str = dev_read_string(ethdev, phy_mode_str[i]);
		if (if_str) {
			interface = phy_get_interface_by_name(if_str);
			break;
		}
	}
	if (interface < 0)
		interface = PHY_INTERFACE_MODE_NONE;
	if (interface == PHY_INTERFACE_MODE_NONE)
		dev_dbg(ethdev, "can't find interface mode, default to NONE\n");

	phy = dm_eth_connect_phy_handle(ethdev, interface);

	if (!phy)
		return NULL;

	phy->interface = interface;

	return phy;
}

UCLASS_DRIVER(mdio) = {
	.id = UCLASS_MDIO,
	.name = "mdio",
	.post_bind  = dm_mdio_post_bind,
	.post_probe = dm_mdio_post_probe,
	.pre_remove = dm_mdio_pre_remove,
	.per_device_auto	= sizeof(struct mdio_perdev_priv),
};
