// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Microchip ksz series register access through SPI
 *
 * Copyright (C) 2017 Microchip Technology Inc.
 *	Tristram Ha <Tristram.Ha@microchip.com>
 */

#include <asm/unaligned.h>

#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>

#include "ksz_common.h"

#define KSZ8795_SPI_ADDR_SHIFT			12
#define KSZ8795_SPI_ADDR_ALIGN			3
#define KSZ8795_SPI_TURNAROUND_SHIFT		1

#define KSZ8863_SPI_ADDR_SHIFT			8
#define KSZ8863_SPI_ADDR_ALIGN			8
#define KSZ8863_SPI_TURNAROUND_SHIFT		0

#define KSZ9477_SPI_ADDR_SHIFT			24
#define KSZ9477_SPI_ADDR_ALIGN			3
#define KSZ9477_SPI_TURNAROUND_SHIFT		5

KSZ_REGMAP_TABLE(ksz8795, 16, KSZ8795_SPI_ADDR_SHIFT,
		 KSZ8795_SPI_TURNAROUND_SHIFT, KSZ8795_SPI_ADDR_ALIGN);

KSZ_REGMAP_TABLE(ksz8863, 16, KSZ8863_SPI_ADDR_SHIFT,
		 KSZ8863_SPI_TURNAROUND_SHIFT, KSZ8863_SPI_ADDR_ALIGN);

KSZ_REGMAP_TABLE(ksz9477, 32, KSZ9477_SPI_ADDR_SHIFT,
		 KSZ9477_SPI_TURNAROUND_SHIFT, KSZ9477_SPI_ADDR_ALIGN);

static int ksz_spi_probe(struct spi_device *spi)
{
	const struct regmap_config *regmap_config;
	const struct ksz_chip_data *chip;
	struct device *ddev = &spi->dev;
	struct regmap_config rc;
	struct ksz_device *dev;
	int i, ret = 0;

	dev = ksz_switch_alloc(&spi->dev, spi);
	if (!dev)
		return -ENOMEM;

	chip = device_get_match_data(ddev);
	if (!chip)
		return -EINVAL;

	if (chip->chip_id == KSZ8830_CHIP_ID)
		regmap_config = ksz8863_regmap_config;
	else if (chip->chip_id == KSZ8795_CHIP_ID ||
		 chip->chip_id == KSZ8794_CHIP_ID ||
		 chip->chip_id == KSZ8765_CHIP_ID)
		regmap_config = ksz8795_regmap_config;
	else
		regmap_config = ksz9477_regmap_config;

	for (i = 0; i < __KSZ_NUM_REGMAPS; i++) {
		rc = regmap_config[i];
		rc.lock_arg = &dev->regmap_mutex;
		rc.wr_table = chip->wr_table;
		rc.rd_table = chip->rd_table;
		dev->regmap[i] = devm_regmap_init_spi(spi, &rc);

		if (IS_ERR(dev->regmap[i])) {
			return dev_err_probe(&spi->dev, PTR_ERR(dev->regmap[i]),
					     "Failed to initialize regmap%i\n",
					     regmap_config[i].val_bits);
		}
	}

	if (spi->dev.platform_data)
		dev->pdata = spi->dev.platform_data;

	/* setup spi */
	spi->mode = SPI_MODE_3;
	ret = spi_setup(spi);
	if (ret)
		return ret;

	dev->irq = spi->irq;

	ret = ksz_switch_register(dev);

	/* Main DSA driver may not be started yet. */
	if (ret)
		return ret;

	spi_set_drvdata(spi, dev);

	return 0;
}

static void ksz_spi_remove(struct spi_device *spi)
{
	struct ksz_device *dev = spi_get_drvdata(spi);

	if (dev)
		ksz_switch_remove(dev);
}

static void ksz_spi_shutdown(struct spi_device *spi)
{
	struct ksz_device *dev = spi_get_drvdata(spi);

	if (!dev)
		return;

	if (dev->dev_ops->reset)
		dev->dev_ops->reset(dev);

	dsa_switch_shutdown(dev->ds);

	spi_set_drvdata(spi, NULL);
}

static const struct of_device_id ksz_dt_ids[] = {
	{
		.compatible = "microchip,ksz8765",
		.data = &ksz_switch_chips[KSZ8765]
	},
	{
		.compatible = "microchip,ksz8794",
		.data = &ksz_switch_chips[KSZ8794]
	},
	{
		.compatible = "microchip,ksz8795",
		.data = &ksz_switch_chips[KSZ8795]
	},
	{
		.compatible = "microchip,ksz8863",
		.data = &ksz_switch_chips[KSZ8830]
	},
	{
		.compatible = "microchip,ksz8873",
		.data = &ksz_switch_chips[KSZ8830]
	},
	{
		.compatible = "microchip,ksz9477",
		.data = &ksz_switch_chips[KSZ9477]
	},
	{
		.compatible = "microchip,ksz9896",
		.data = &ksz_switch_chips[KSZ9896]
	},
	{
		.compatible = "microchip,ksz9897",
		.data = &ksz_switch_chips[KSZ9897]
	},
	{
		.compatible = "microchip,ksz9893",
		.data = &ksz_switch_chips[KSZ9893]
	},
	{
		.compatible = "microchip,ksz9563",
		.data = &ksz_switch_chips[KSZ9563]
	},
	{
		.compatible = "microchip,ksz8563",
		.data = &ksz_switch_chips[KSZ8563]
	},
	{
		.compatible = "microchip,ksz9567",
		.data = &ksz_switch_chips[KSZ9567]
	},
	{
		.compatible = "microchip,lan9370",
		.data = &ksz_switch_chips[LAN9370]
	},
	{
		.compatible = "microchip,lan9371",
		.data = &ksz_switch_chips[LAN9371]
	},
	{
		.compatible = "microchip,lan9372",
		.data = &ksz_switch_chips[LAN9372]
	},
	{
		.compatible = "microchip,lan9373",
		.data = &ksz_switch_chips[LAN9373]
	},
	{
		.compatible = "microchip,lan9374",
		.data = &ksz_switch_chips[LAN9374]
	},
	{},
};
MODULE_DEVICE_TABLE(of, ksz_dt_ids);

static const struct spi_device_id ksz_spi_ids[] = {
	{ "ksz8765" },
	{ "ksz8794" },
	{ "ksz8795" },
	{ "ksz8863" },
	{ "ksz8873" },
	{ "ksz9477" },
	{ "ksz9896" },
	{ "ksz9897" },
	{ "ksz9893" },
	{ "ksz9563" },
	{ "ksz8563" },
	{ "ksz9567" },
	{ "lan9370" },
	{ "lan9371" },
	{ "lan9372" },
	{ "lan9373" },
	{ "lan9374" },
	{ },
};
MODULE_DEVICE_TABLE(spi, ksz_spi_ids);

static struct spi_driver ksz_spi_driver = {
	.driver = {
		.name	= "ksz-switch",
		.owner	= THIS_MODULE,
		.of_match_table = ksz_dt_ids,
	},
	.id_table = ksz_spi_ids,
	.probe	= ksz_spi_probe,
	.remove	= ksz_spi_remove,
	.shutdown = ksz_spi_shutdown,
};

module_spi_driver(ksz_spi_driver);

MODULE_ALIAS("spi:ksz9477");
MODULE_ALIAS("spi:ksz9896");
MODULE_ALIAS("spi:ksz9897");
MODULE_ALIAS("spi:ksz9893");
MODULE_ALIAS("spi:ksz9563");
MODULE_ALIAS("spi:ksz8563");
MODULE_ALIAS("spi:ksz9567");
MODULE_ALIAS("spi:lan937x");
MODULE_AUTHOR("Tristram Ha <Tristram.Ha@microchip.com>");
MODULE_DESCRIPTION("Microchip ksz Series Switch SPI Driver");
MODULE_LICENSE("GPL");
