File Index
Files and directories
Sign in
FILE

wmt-socinfo.c

File preview with syntax highlighting.

linux-6.19.14/drivers/soc/vt8500/wmt-socinfo.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Copyright 2025 Alexey Charkov <alchark@gmail.com>
  4 * Based on aspeed-socinfo.c
  5 */
  6
  7#include <linux/dev_printk.h>
  8#include <linux/device.h>
  9#include <linux/io.h>
 10#include <linux/of.h>
 11#include <linux/platform_device.h>
 12#include <linux/sys_soc.h>
 13
 14static const struct {
 15	const char *name;
 16	const u32 id;
 17} chip_id_table[] = {
 18	/* VIA */
 19	{ "VT8420", 0x3300 },
 20	{ "VT8430", 0x3357 },
 21	{ "VT8500", 0x3400 },
 22
 23	/* WonderMedia */
 24	{ "WM8425", 0x3429 },
 25	{ "WM8435", 0x3437 },
 26	{ "WM8440", 0x3451 },
 27	{ "WM8505", 0x3426 },
 28	{ "WM8650", 0x3465 },
 29	{ "WM8750", 0x3445 },
 30	{ "WM8850", 0x3481 },
 31	{ "WM8880", 0x3498 },
 32};
 33
 34static const char *sccid_to_name(u32 sccid)
 35{
 36	u32 id = sccid >> 16;
 37	unsigned int i;
 38
 39	for (i = 0 ; i < ARRAY_SIZE(chip_id_table) ; ++i) {
 40		if (chip_id_table[i].id == id)
 41			return chip_id_table[i].name;
 42	}
 43
 44	return "Unknown";
 45}
 46
 47static int wmt_socinfo_probe(struct platform_device *pdev)
 48{
 49	struct device_node *np = pdev->dev.of_node;
 50	struct soc_device_attribute *attrs;
 51	struct soc_device *soc_dev;
 52	char letter, digit;
 53	void __iomem *reg;
 54	u32 sccid;
 55
 56	reg = devm_of_iomap(&pdev->dev, np, 0, NULL);
 57	if (IS_ERR(reg))
 58		return PTR_ERR(reg);
 59
 60	sccid = readl(reg);
 61
 62	attrs = devm_kzalloc(&pdev->dev, sizeof(*attrs), GFP_KERNEL);
 63	if (!attrs)
 64		return -ENOMEM;
 65
 66	/*
 67	 * Machine: VIA APC Rock
 68	 * Family: WM8850
 69	 * Revision: A2
 70	 * SoC ID: raw silicon revision id (34810103 in hexadecimal)
 71	 */
 72
 73	attrs->family = sccid_to_name(sccid);
 74
 75	letter = (sccid >> 8) & 0xf;
 76	letter = (letter - 1) + 'A';
 77	digit = sccid & 0xff;
 78	digit = (digit - 1) + '0';
 79	attrs->revision = devm_kasprintf(&pdev->dev, GFP_KERNEL,
 80					 "%c%c", letter, digit);
 81
 82	attrs->soc_id = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%08x", sccid);
 83
 84	if (!attrs->revision || !attrs->soc_id)
 85		return -ENOMEM;
 86
 87	soc_dev = soc_device_register(attrs);
 88	if (IS_ERR(soc_dev))
 89		return PTR_ERR(soc_dev);
 90
 91	dev_info(&pdev->dev,
 92		 "VIA/WonderMedia %s rev %s (%s)\n",
 93		 attrs->family,
 94		 attrs->revision,
 95		 attrs->soc_id);
 96
 97	platform_set_drvdata(pdev, soc_dev);
 98	return 0;
 99}
100
101static void wmt_socinfo_remove(struct platform_device *pdev)
102{
103	struct soc_device *soc_dev = platform_get_drvdata(pdev);
104
105	soc_device_unregister(soc_dev);
106}
107
108static const struct of_device_id wmt_socinfo_ids[] = {
109	{ .compatible = "via,vt8500-scc-id" },
110	{ /* Sentinel */ },
111};
112
113static struct platform_driver wmt_socinfo = {
114	.probe = wmt_socinfo_probe,
115	.remove = wmt_socinfo_remove,
116	.driver = {
117		.name = "wmt-socinfo",
118		.of_match_table = wmt_socinfo_ids,
119	},
120};
121module_platform_driver(wmt_socinfo);
122
123MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");
124MODULE_DESCRIPTION("VIA/WonderMedia socinfo driver");
125MODULE_LICENSE("GPL");
~/ Read-only file preview.