// 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, bool dual_sgmii)
{
	struct regmap_config *mt7531_pcs_config[2] = {};
	struct phylink_pcs *pcs;
	struct regmap *regmap;
	int i, ret = 0;

	/* MT7531AE has two SGMII units for port 5 and port 6
	 * MT7531BE has only one SGMII unit for port 6
	 */
	for (i = dual_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");
