// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2014 Linaro Ltd.
 *
 * Author: Linus Walleij <linus.walleij@linaro.org>
 */
#include <linux/init.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/sys_soc.h>
#include <linux/platform_device.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/of.h>

#define INTEGRATOR_HDR_ID_OFFSET	0x00

static u32 integrator_coreid;

static const struct of_device_id integrator_cm_match[] = {
	{ .compatible = "arm,core-module-integrator", },
	{ }
};

static const char *integrator_arch_str(u32 id)
{
	switch ((id >> 16) & 0xff) {
	case 0x00:
		return "ASB little-endian";
	case 0x01:
		return "AHB little-endian";
	case 0x03:
		return "AHB-Lite system bus, bi-endian";
	case 0x04:
		return "AHB";
	case 0x08:
		return "AHB system bus, ASB processor bus";
	default:
		return "Unknown";
	}
}

static const char *integrator_fpga_str(u32 id)
{
	switch ((id >> 12) & 0xf) {
	case 0x01:
		return "XC4062";
	case 0x02:
		return "XC4085";
	case 0x03:
		return "XVC600";
	case 0x04:
		return "EPM7256AE (Altera PLD)";
	default:
		return "Unknown";
	}
}

static ssize_t
manufacturer_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%02x\n", integrator_coreid >> 24);
}

static DEVICE_ATTR_RO(manufacturer);

static ssize_t
arch_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%s\n", integrator_arch_str(integrator_coreid));
}

static DEVICE_ATTR_RO(arch);

static ssize_t
fpga_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%s\n", integrator_fpga_str(integrator_coreid));
}

static DEVICE_ATTR_RO(fpga);

static ssize_t
build_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%02x\n", (integrator_coreid >> 4) & 0xFF);
}

static DEVICE_ATTR_RO(build);

static struct attribute *integrator_attrs[] = {
	&dev_attr_manufacturer.attr,
	&dev_attr_arch.attr,
	&dev_attr_fpga.attr,
	&dev_attr_build.attr,
	NULL
};

ATTRIBUTE_GROUPS(integrator);

static int __init integrator_soc_init(void)
{
	static struct regmap *syscon_regmap;
	struct soc_device *soc_dev;
	struct soc_device_attribute *soc_dev_attr;
	struct device_node *np;
	struct device *dev;
	u32 val;
	int ret;

	np = of_find_matching_node(NULL, integrator_cm_match);
	if (!np)
		return -ENODEV;

	syscon_regmap = syscon_node_to_regmap(np);
	if (IS_ERR(syscon_regmap))
		return PTR_ERR(syscon_regmap);

	ret = regmap_read(syscon_regmap, INTEGRATOR_HDR_ID_OFFSET,
			  &val);
	if (ret)
		return -ENODEV;
	integrator_coreid = val;

	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
	if (!soc_dev_attr)
		return -ENOMEM;

	soc_dev_attr->soc_id = "Integrator";
	soc_dev_attr->machine = "Integrator";
	soc_dev_attr->family = "Versatile";
	soc_dev_attr->custom_attr_group = integrator_groups[0];
	soc_dev = soc_device_register(soc_dev_attr);
	if (IS_ERR(soc_dev)) {
		kfree(soc_dev_attr);
		return -ENODEV;
	}
	dev = soc_device_to_device(soc_dev);

	dev_info(dev, "Detected ARM core module:\n");
	dev_info(dev, "    Manufacturer: %02x\n", (val >> 24));
	dev_info(dev, "    Architecture: %s\n", integrator_arch_str(val));
	dev_info(dev, "    FPGA: %s\n", integrator_fpga_str(val));
	dev_info(dev, "    Build: %02x\n", (val >> 4) & 0xFF);
	dev_info(dev, "    Rev: %c\n", ('A' + (val & 0x03)));

	return 0;
}
device_initcall(integrator_soc_init);
