Linux Audio

Check our new training course

Loading...
v5.9
  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	u32 *val = _val;
 23	int i = 0, words = bytes / 4;
 
 
 
 24
 25	while (words--)
 26		*val++ = readl(priv->base + reg + (i++ * 4));
 
 
 27
 28	return 0;
 29}
 
 30
 31static int mtk_reg_write(void *context,
 32			 unsigned int reg, void *_val, size_t bytes)
 33{
 34	struct mtk_efuse_priv *priv = context;
 35	u32 *val = _val;
 36	int i = 0, words = bytes / 4;
 
 
 
 
 
 
 
 37
 38	while (words--)
 39		writel(*val++, priv->base + reg + (i++ * 4));
 40
 41	return 0;
 42}
 43
 44static int mtk_efuse_probe(struct platform_device *pdev)
 45{
 46	struct device *dev = &pdev->dev;
 47	struct resource *res;
 48	struct nvmem_device *nvmem;
 49	struct nvmem_config econfig = {};
 50	struct mtk_efuse_priv *priv;
 51
 52	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 53	if (!priv)
 54		return -ENOMEM;
 55
 56	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 57	priv->base = devm_ioremap_resource(dev, res);
 58	if (IS_ERR(priv->base))
 59		return PTR_ERR(priv->base);
 60
 61	econfig.stride = 4;
 62	econfig.word_size = 4;
 63	econfig.reg_read = mtk_reg_read;
 64	econfig.reg_write = mtk_reg_write;
 65	econfig.size = resource_size(res);
 66	econfig.priv = priv;
 67	econfig.dev = dev;
 68	nvmem = devm_nvmem_register(dev, &econfig);
 69
 70	return PTR_ERR_OR_ZERO(nvmem);
 71}
 72
 73static const struct of_device_id mtk_efuse_of_match[] = {
 74	{ .compatible = "mediatek,mt8173-efuse",},
 75	{ .compatible = "mediatek,efuse",},
 76	{/* sentinel */},
 77};
 78MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
 79
 80static struct platform_driver mtk_efuse_driver = {
 81	.probe = mtk_efuse_probe,
 
 82	.driver = {
 83		.name = "mediatek,efuse",
 84		.of_match_table = mtk_efuse_of_match,
 85	},
 86};
 87
 88static int __init mtk_efuse_init(void)
 89{
 90	int ret;
 91
 92	ret = platform_driver_register(&mtk_efuse_driver);
 93	if (ret) {
 94		pr_err("Failed to register efuse driver\n");
 95		return ret;
 96	}
 97
 98	return 0;
 99}
100
101static void __exit mtk_efuse_exit(void)
102{
103	return platform_driver_unregister(&mtk_efuse_driver);
104}
105
106subsys_initcall(mtk_efuse_init);
107module_exit(mtk_efuse_exit);
108
109MODULE_AUTHOR("Andrew-CT Chen <andrew-ct.chen@mediatek.com>");
110MODULE_DESCRIPTION("Mediatek EFUSE driver");
111MODULE_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");