brintos

brintos / linux-shallow public Read only

0
0
Text · 2.2 KiB · c5e0d11 Raw
110 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Nuvoton WPCM450 SoC Identification4 *5 * Copyright (C) 2022 Jonathan Neuschäfer6 */7 8#include <linux/mfd/syscon.h>9#include <linux/of.h>10#include <linux/regmap.h>11#include <linux/slab.h>12#include <linux/sys_soc.h>13 14#define GCR_PDID	015#define PDID_CHIP(x)	((x) & 0x00ffffff)16#define CHIP_WPCM450	0x92645017#define PDID_REV(x)	((x) >> 24)18 19struct revision {20	u8 number;21	const char *name;22};23 24static const struct revision revisions[] __initconst = {25	{ 0x00, "Z1" },26	{ 0x03, "Z2" },27	{ 0x04, "Z21" },28	{ 0x08, "A1" },29	{ 0x09, "A2" },30	{ 0x0a, "A3" },31	{}32};33 34static const char * __init get_revision(unsigned int rev)35{36	int i;37 38	for (i = 0; revisions[i].name; i++)39		if (revisions[i].number == rev)40			return revisions[i].name;41	return NULL;42}43 44static struct soc_device_attribute *wpcm450_attr;45static struct soc_device *wpcm450_soc;46 47static int __init wpcm450_soc_init(void)48{49	struct soc_device_attribute *attr;50	struct soc_device *soc;51	const char *revision;52	struct regmap *gcr;53	u32 pdid;54	int ret;55 56	if (!of_machine_is_compatible("nuvoton,wpcm450"))57		return 0;58 59	gcr = syscon_regmap_lookup_by_compatible("nuvoton,wpcm450-gcr");60	if (IS_ERR(gcr))61		return PTR_ERR(gcr);62	ret = regmap_read(gcr, GCR_PDID, &pdid);63	if (ret)64		return ret;65 66	if (PDID_CHIP(pdid) != CHIP_WPCM450) {67		pr_warn("Unknown chip ID in GCR.PDID: 0x%06x\n", PDID_CHIP(pdid));68		return -ENODEV;69	}70 71	revision = get_revision(PDID_REV(pdid));72	if (!revision) {73		pr_warn("Unknown chip revision in GCR.PDID: 0x%02x\n", PDID_REV(pdid));74		return -ENODEV;75	}76 77	attr = kzalloc(sizeof(*attr), GFP_KERNEL);78	if (!attr)79		return -ENOMEM;80 81	attr->family = "Nuvoton NPCM";82	attr->soc_id = "WPCM450";83	attr->revision = revision;84	soc = soc_device_register(attr);85	if (IS_ERR(soc)) {86		kfree(attr);87		pr_warn("Could not register SoC device\n");88		return PTR_ERR(soc);89	}90 91	wpcm450_soc = soc;92	wpcm450_attr = attr;93	return 0;94}95module_init(wpcm450_soc_init);96 97static void __exit wpcm450_soc_exit(void)98{99	if (wpcm450_soc) {100		soc_device_unregister(wpcm450_soc);101		wpcm450_soc = NULL;102		kfree(wpcm450_attr);103	}104}105module_exit(wpcm450_soc_exit);106 107MODULE_LICENSE("GPL");108MODULE_AUTHOR("Jonathan Neuschäfer");109MODULE_DESCRIPTION("Nuvoton WPCM450 SoC Identification driver");110