// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2023 MediaTek Inc.
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
#include <linux/nvmem-consumer.h>
#include <linux/device.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/string.h>
#include <linux/sys_soc.h>
#include <linux/slab.h>
#include <linux/platform_device.h>

#define MTK_SOCINFO_ENTRY(_soc_name, _segment_name, _marketing_name, _cell_data1, _cell_data2) {\
	.soc_name = _soc_name,									\
	.segment_name = _segment_name,								\
	.marketing_name = _marketing_name,							\
	.cell_data = {_cell_data1, _cell_data2}							\
}
#define CELL_NOT_USED (0xFFFFFFFF)
#define MAX_CELLS (2)

struct mtk_socinfo {
	struct device *dev;
	struct name_data *name_data;
	struct socinfo_data *socinfo_data;
	struct soc_device *soc_dev;
};

struct socinfo_data {
	char *soc_name;
	char *segment_name;
	char *marketing_name;
	u32 cell_data[MAX_CELLS];
};

static const char *cell_names[MAX_CELLS] = {"socinfo-data1", "socinfo-data2"};

static struct socinfo_data socinfo_data_table[] = {
	MTK_SOCINFO_ENTRY("MT8173", "MT8173V/AC", "MT8173", 0x6CA20004, 0x10000000),
	MTK_SOCINFO_ENTRY("MT8183", "MT8183V/AZA", "Kompanio 500", 0x00010043, 0x00000840),
	MTK_SOCINFO_ENTRY("MT8186", "MT8186GV/AZA", "Kompanio 520", 0x81861001, CELL_NOT_USED),
	MTK_SOCINFO_ENTRY("MT8186T", "MT8186TV/AZA", "Kompanio 528", 0x81862001, CELL_NOT_USED),
	MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/AZA", "Kompanio 830", 0x81880000, 0x00000010),
	MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/HZA", "Kompanio 830", 0x81880000, 0x00000011),
	MTK_SOCINFO_ENTRY("MT8192", "MT8192V/AZA", "Kompanio 820", 0x00001100, 0x00040080),
	MTK_SOCINFO_ENTRY("MT8192T", "MT8192V/ATZA", "Kompanio 828", 0x00000100, 0x000400C0),
	MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EZA", "Kompanio 1200", 0x81950300, CELL_NOT_USED),
	MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EHZA", "Kompanio 1200", 0x81950304, CELL_NOT_USED),
	MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EZA", "Kompanio 1380", 0x81950400, CELL_NOT_USED),
	MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EHZA", "Kompanio 1380", 0x81950404, CELL_NOT_USED),
};

static int mtk_socinfo_create_socinfo_node(struct mtk_socinfo *mtk_socinfop)
{
	struct soc_device_attribute *attrs;
	static char machine[30] = {0};
	static const char *soc_manufacturer = "MediaTek";

	attrs = devm_kzalloc(mtk_socinfop->dev, sizeof(*attrs), GFP_KERNEL);
	if (!attrs)
		return -ENOMEM;

	snprintf(machine, sizeof(machine), "%s (%s)", mtk_socinfop->socinfo_data->marketing_name,
		mtk_socinfop->socinfo_data->soc_name);
	attrs->family = soc_manufacturer;
	attrs->machine = machine;

	mtk_socinfop->soc_dev = soc_device_register(attrs);
	if (IS_ERR(mtk_socinfop->soc_dev))
		return PTR_ERR(mtk_socinfop->soc_dev);

	dev_info(mtk_socinfop->dev, "%s %s SoC detected.\n", soc_manufacturer, attrs->machine);
	return 0;
}

static u32 mtk_socinfo_read_cell(struct device *dev, const char *name)
{
	struct nvmem_device *nvmemp;
	struct device_node *np = dev->of_node;
	u32 offset;
	u32 cell_val = CELL_NOT_USED;

	nvmemp = devm_nvmem_device_get(dev, "mtk-efuse0");
	if (IS_ERR(nvmemp))
		goto out;

	np = of_find_node_by_name(NULL, name);
	if (!np)
		goto out;

	if (of_property_read_u32_index(np, "reg", 0, &offset))
		goto out;

	nvmem_device_read(nvmemp, offset, sizeof(cell_val), &cell_val);

	nvmem_device_put(nvmemp);

out:
	return cell_val;
}

static int mtk_socinfo_get_socinfo_data(struct mtk_socinfo *mtk_socinfop)
{
	unsigned int i, j;
	unsigned int num_cell_data = 0;
	u32 cell_data[MAX_CELLS] = {0};
	bool match_socinfo;
	int match_socinfo_index = -1;

	for (i = 0; i < MAX_CELLS; i++) {
		cell_data[i] = mtk_socinfo_read_cell(mtk_socinfop->dev, cell_names[i]);
		if (cell_data[i] != CELL_NOT_USED)
			num_cell_data++;
		else
			break;
	}

	if (!num_cell_data)
		return -ENOENT;

	for (i = 0; i < ARRAY_SIZE(socinfo_data_table); i++) {
		match_socinfo = true;
		for (j = 0; j < num_cell_data; j++) {
			if (cell_data[j] != socinfo_data_table[i].cell_data[j]) {
				match_socinfo = false;
				break;
			}
		}
		if (match_socinfo) {
			mtk_socinfop->socinfo_data = &(socinfo_data_table[i]);
			match_socinfo_index = i;
			break;
		}
	}

	return match_socinfo_index >= 0 ? match_socinfo_index : -ENOENT;
}

static int mtk_socinfo_probe(struct platform_device *pdev)
{
	struct mtk_socinfo *mtk_socinfop;
	int ret;

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

	mtk_socinfop->dev = &pdev->dev;

	ret = mtk_socinfo_get_socinfo_data(mtk_socinfop);
	if (ret < 0)
		return dev_err_probe(mtk_socinfop->dev, ret, "Failed to get socinfo data\n");

	ret = mtk_socinfo_create_socinfo_node(mtk_socinfop);
	if (ret)
		return dev_err_probe(mtk_socinfop->dev, ret, "Cannot create node\n");

	platform_set_drvdata(pdev, mtk_socinfop);
	return 0;
}

static int mtk_socinfo_remove(struct platform_device *pdev)
{
	struct mtk_socinfo *mtk_socinfop = platform_get_drvdata(pdev);

	soc_device_unregister(mtk_socinfop->soc_dev);
	return 0;
}

static struct platform_driver mtk_socinfo = {
	.probe = mtk_socinfo_probe,
	.remove = mtk_socinfo_remove,
	.driver = {
		.name = "mtk-socinfo",
	},
};
module_platform_driver(mtk_socinfo);

MODULE_AUTHOR("William-TW LIN <william-tw.lin@mediatek.com>");
MODULE_DESCRIPTION("MediaTek socinfo driver");
MODULE_LICENSE("GPL");
