Linux Audio

Check our new training course

Loading...
v6.2
 1// SPDX-License-Identifier: GPL-2.0-only
 2/*
 3 * Copyright (c) 2015 MediaTek Inc.
 4 * Author: Andrew-CT Chen <andrew-ct.chen@mediatek.com>
 
 
 
 
 
 
 
 
 
 5 */
 6
 7#include <linux/device.h>
 8#include <linux/module.h>
 9#include <linux/mod_devicetable.h>
10#include <linux/io.h>
11#include <linux/nvmem-provider.h>
12#include <linux/platform_device.h>
 
13
14struct mtk_efuse_priv {
15	void __iomem *base;
 
 
16};
17
18static int mtk_reg_read(void *context,
19			unsigned int reg, void *_val, size_t bytes)
20{
21	struct mtk_efuse_priv *priv = context;
22	void __iomem *addr = priv->base + reg;
23	u8 *val = _val;
24	int i;
25
26	for (i = 0; i < bytes; i++, val++)
27		*val = readb(addr + i);
28
29	return 0;
30}
31
32static int mtk_efuse_probe(struct platform_device *pdev)
33{
34	struct device *dev = &pdev->dev;
35	struct resource *res;
36	struct nvmem_device *nvmem;
37	struct nvmem_config econfig = {};
38	struct mtk_efuse_priv *priv;
 
39
40	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
41	if (!priv)
 
 
 
 
 
42		return -ENOMEM;
43
44	priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
45	if (IS_ERR(priv->base))
46		return PTR_ERR(priv->base);
47
48	econfig.stride = 1;
49	econfig.word_size = 1;
50	econfig.reg_read = mtk_reg_read;
51	econfig.size = resource_size(res);
52	econfig.priv = priv;
53	econfig.dev = dev;
54	nvmem = devm_nvmem_register(dev, &econfig);
 
 
 
 
 
 
 
 
 
 
 
55
56	return PTR_ERR_OR_ZERO(nvmem);
57}
58
59static const struct of_device_id mtk_efuse_of_match[] = {
60	{ .compatible = "mediatek,mt8173-efuse",},
61	{ .compatible = "mediatek,efuse",},
62	{/* sentinel */},
63};
64MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
65
66static struct platform_driver mtk_efuse_driver = {
67	.probe = mtk_efuse_probe,
 
68	.driver = {
69		.name = "mediatek,efuse",
70		.of_match_table = mtk_efuse_of_match,
71	},
72};
73
74static int __init mtk_efuse_init(void)
75{
76	int ret;
77
78	ret = platform_driver_register(&mtk_efuse_driver);
79	if (ret) {
80		pr_err("Failed to register efuse driver\n");
81		return ret;
82	}
83
84	return 0;
85}
86
87static void __exit mtk_efuse_exit(void)
88{
89	return platform_driver_unregister(&mtk_efuse_driver);
90}
91
92subsys_initcall(mtk_efuse_init);
93module_exit(mtk_efuse_exit);
94
95MODULE_AUTHOR("Andrew-CT Chen <andrew-ct.chen@mediatek.com>");
96MODULE_DESCRIPTION("Mediatek EFUSE driver");
97MODULE_LICENSE("GPL v2");
v4.6
 
  1/*
  2 * Copyright (c) 2015 MediaTek Inc.
  3 * Author: Andrew-CT Chen <andrew-ct.chen@mediatek.com>
  4 *
  5 * This program is free software; you can redistribute it and/or modify
  6 * it under the terms of the GNU General Public License version 2 as
  7 * published by the Free Software Foundation.
  8 *
  9 * This program is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12 * GNU General Public License for more details.
 13 */
 14
 15#include <linux/device.h>
 16#include <linux/module.h>
 
 
 17#include <linux/nvmem-provider.h>
 18#include <linux/platform_device.h>
 19#include <linux/regmap.h>
 20
 21static struct regmap_config mtk_regmap_config = {
 22	.reg_bits = 32,
 23	.val_bits = 32,
 24	.reg_stride = 4,
 25};
 26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 27static int mtk_efuse_probe(struct platform_device *pdev)
 28{
 29	struct device *dev = &pdev->dev;
 30	struct resource *res;
 31	struct nvmem_device *nvmem;
 32	struct nvmem_config *econfig;
 33	struct regmap *regmap;
 34	void __iomem *base;
 35
 36	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 37	base = devm_ioremap_resource(dev, res);
 38	if (IS_ERR(base))
 39		return PTR_ERR(base);
 40
 41	econfig = devm_kzalloc(dev, sizeof(*econfig), GFP_KERNEL);
 42	if (!econfig)
 43		return -ENOMEM;
 44
 45	mtk_regmap_config.max_register = resource_size(res) - 1;
 46
 47	regmap = devm_regmap_init_mmio(dev, base, &mtk_regmap_config);
 48	if (IS_ERR(regmap)) {
 49		dev_err(dev, "regmap init failed\n");
 50		return PTR_ERR(regmap);
 51	}
 52
 53	econfig->dev = dev;
 54	econfig->owner = THIS_MODULE;
 55	nvmem = nvmem_register(econfig);
 56	if (IS_ERR(nvmem))
 57		return PTR_ERR(nvmem);
 58
 59	platform_set_drvdata(pdev, nvmem);
 60
 61	return 0;
 62}
 63
 64static int mtk_efuse_remove(struct platform_device *pdev)
 65{
 66	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
 67
 68	return nvmem_unregister(nvmem);
 69}
 70
 71static const struct of_device_id mtk_efuse_of_match[] = {
 72	{ .compatible = "mediatek,mt8173-efuse",},
 73	{ .compatible = "mediatek,efuse",},
 74	{/* sentinel */},
 75};
 76MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
 77
 78static struct platform_driver mtk_efuse_driver = {
 79	.probe = mtk_efuse_probe,
 80	.remove = mtk_efuse_remove,
 81	.driver = {
 82		.name = "mediatek,efuse",
 83		.of_match_table = mtk_efuse_of_match,
 84	},
 85};
 86
 87static int __init mtk_efuse_init(void)
 88{
 89	int ret;
 90
 91	ret = platform_driver_register(&mtk_efuse_driver);
 92	if (ret) {
 93		pr_err("Failed to register efuse driver\n");
 94		return ret;
 95	}
 96
 97	return 0;
 98}
 99
100static void __exit mtk_efuse_exit(void)
101{
102	return platform_driver_unregister(&mtk_efuse_driver);
103}
104
105subsys_initcall(mtk_efuse_init);
106module_exit(mtk_efuse_exit);
107
108MODULE_AUTHOR("Andrew-CT Chen <andrew-ct.chen@mediatek.com>");
109MODULE_DESCRIPTION("Mediatek EFUSE driver");
110MODULE_LICENSE("GPL v2");