// SPDX-License-Identifier: GPL-2.0-only

#include <linux/gpio/consumer.h>
#include <linux/mdio.h>
#include <linux/module.h>
#include <linux/pcs/pcs-mtk-lynxi.h>
#include <linux/of_irq.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/of_platform.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/regulator/consumer.h>
#include <net/dsa.h>

#include "mt7530.h"

static int
mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
{
	struct mii_bus *bus = context;
	u16 page, r, lo, hi;
	int ret;

	page = (reg >> 6) & 0x3ff;
	r  = (reg >> 2) & 0xf;
	lo = val & 0xffff;
	hi = val >> 16;

	/* MT7530 uses 31 as the pseudo port */
	ret = bus->write(bus, 0x1f, 0x1f, page);
	if (ret < 0)
		return ret;

	ret = bus->write(bus, 0x1f, r,  lo);
	if (ret < 0)
		return ret;

	ret = bus->write(bus, 0x1f, 0x10, hi);
	return ret;
}

static int
mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
{
	struct mii_bus *bus = context;
	u16 page, r, lo, hi;
	int ret;

	page = (reg >> 6) & 0x3ff;
	r = (reg >> 2) & 0xf;

	/* MT7530 uses 31 as the pseudo port */
	ret = bus->write(bus, 0x1f, 0x1f, page);
	if (ret < 0)
		return ret;

	lo = bus->read(bus, 0x1f, r);
	hi = bus->read(bus, 0x1f, 0x10);

	*val = (hi << 16) | (lo & 0xffff);

	return 0;
}

static void
mt7530_mdio_regmap_lock(void *mdio_lock)
{
	mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
}

static void
mt7530_mdio_regmap_unlock(void *mdio_lock)
{
	mutex_unlock(mdio_lock);
}

static const struct regmap_bus mt7530_regmap_bus = {
	.reg_write = mt7530_regmap_write,
	.reg_read = mt7530_regmap_read,
};

static int
mt7531_create_sgmii(struct mt7530_priv *priv)
{
	struct regmap_config *mt7531_pcs_config[2] = {};
	struct phylink_pcs *pcs;
	struct regmap *regmap;
	int i, ret = 0;

	for (i = priv->p5_sgmii ? 0 : 1; i < 2; i++) {
		mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
						    sizeof(struct regmap_config),
						    GFP_KERNEL);
		if (!mt7531_pcs_config[i]) {
			ret = -ENOMEM;
			break;
		}

		mt7531_pcs_config[i]->name = i ? "port6" : "port5";
		mt7531_pcs_config[i]->reg_bits = 16;
		mt7531_pcs_config[i]->val_bits = 32;
		mt7531_pcs_config[i]->reg_stride = 4;
		mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
		mt7531_pcs_config[i]->max_register = 0x17c;
		mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
		mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
		mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;

		regmap = devm_regmap_init(priv->dev,
					  &mt7530_regmap_bus, priv->bus,
					  mt7531_pcs_config[i]);
		if (IS_ERR(regmap)) {
			ret = PTR_ERR(regmap);
			break;
		}
		pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
					   MT7531_PHYA_CTRL_SIGNAL3, 0);
		if (!pcs) {
			ret = -ENXIO;
			break;
		}
		priv->ports[5 + i].sgmii_pcs = pcs;
	}

	if (ret && i)
		mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);

	return ret;
}

static const struct of_device_id mt7530_of_match[] = {
	{ .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
	{ .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
	{ .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mt7530_of_match);

static int
mt7530_probe(struct mdio_device *mdiodev)
{
	static struct regmap_config *regmap_config;
	struct mt7530_priv *priv;
	struct device_node *dn;
	int ret;

	dn = mdiodev->dev.of_node;

	priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->bus = mdiodev->bus;
	priv->dev = &mdiodev->dev;

	ret = mt7530_probe_common(priv);
	if (ret)
		return ret;

	/* Use medatek,mcm property to distinguish hardware type that would
	 * cause a little bit differences on power-on sequence.
	 * Not MCM that indicates switch works as the remote standalone
	 * integrated circuit so the GPIO pin would be used to complete
	 * the reset, otherwise memory-mapped register accessing used
	 * through syscon provides in the case of MCM.
	 */
	priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
	if (priv->mcm) {
		dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");

		priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
		if (IS_ERR(priv->rstc)) {
			dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
			return PTR_ERR(priv->rstc);
		}
	} else {
		priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
						      GPIOD_OUT_LOW);
		if (IS_ERR(priv->reset)) {
			dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
			return PTR_ERR(priv->reset);
		}
	}

	if (priv->id == ID_MT7530) {
		priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
		if (IS_ERR(priv->core_pwr))
			return PTR_ERR(priv->core_pwr);

		priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
		if (IS_ERR(priv->io_pwr))
			return PTR_ERR(priv->io_pwr);
	}

	regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
				     GFP_KERNEL);
	if (!regmap_config)
		return -ENOMEM;

	regmap_config->reg_bits = 16;
	regmap_config->val_bits = 32;
	regmap_config->reg_stride = 4;
	regmap_config->max_register = MT7530_CREV;
	regmap_config->disable_locking = true;
	priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
					priv->bus, regmap_config);
	if (IS_ERR(priv->regmap))
		return PTR_ERR(priv->regmap);

	if (priv->id == ID_MT7531)
		priv->create_sgmii = mt7531_create_sgmii;

	return dsa_register_switch(priv->ds);
}

static void
mt7530_remove(struct mdio_device *mdiodev)
{
	struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
	int ret = 0, i;

	if (!priv)
		return;

	ret = regulator_disable(priv->core_pwr);
	if (ret < 0)
		dev_err(priv->dev,
			"Failed to disable core power: %d\n", ret);

	ret = regulator_disable(priv->io_pwr);
	if (ret < 0)
		dev_err(priv->dev, "Failed to disable io pwr: %d\n",
			ret);

	mt7530_remove_common(priv);

	for (i = 0; i < 2; ++i)
		mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
}

static void mt7530_shutdown(struct mdio_device *mdiodev)
{
	struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);

	if (!priv)
		return;

	dsa_switch_shutdown(priv->ds);

	dev_set_drvdata(&mdiodev->dev, NULL);
}

static struct mdio_driver mt7530_mdio_driver = {
	.probe  = mt7530_probe,
	.remove = mt7530_remove,
	.shutdown = mt7530_shutdown,
	.mdiodrv.driver = {
		.name = "mt7530-mdio",
		.of_match_table = mt7530_of_match,
	},
};

mdio_module_driver(mt7530_mdio_driver);

MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MDIO)");
MODULE_LICENSE("GPL");
