brintos

brintos / linux-shallow public Read only

0
0
Text · 3.0 KiB · f13bbd1 Raw
144 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * i.MX IIM driver4 *5 * Copyright (c) 2017 Pengutronix, Michael Grzeschik <m.grzeschik@pengutronix.de>6 *7 * Based on the barebox iim driver,8 * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>,9 *	Orex Computed Radiography10 */11 12#include <linux/device.h>13#include <linux/io.h>14#include <linux/module.h>15#include <linux/nvmem-provider.h>16#include <linux/of.h>17#include <linux/platform_device.h>18#include <linux/slab.h>19#include <linux/clk.h>20 21#define IIM_BANK_BASE(n)	(0x800 + 0x400 * (n))22 23struct imx_iim_drvdata {24	unsigned int nregs;25};26 27struct iim_priv {28	void __iomem *base;29	struct clk *clk;30};31 32static int imx_iim_read(void *context, unsigned int offset,33			  void *buf, size_t bytes)34{35	struct iim_priv *iim = context;36	int i, ret;37	u8 *buf8 = buf;38 39	ret = clk_prepare_enable(iim->clk);40	if (ret)41		return ret;42 43	for (i = offset; i < offset + bytes; i++) {44		int bank = i >> 5;45		int reg = i & 0x1f;46 47		*buf8++ = readl(iim->base + IIM_BANK_BASE(bank) + reg * 4);48	}49 50	clk_disable_unprepare(iim->clk);51 52	return 0;53}54 55static struct imx_iim_drvdata imx27_drvdata = {56	.nregs = 2 * 32,57};58 59static struct imx_iim_drvdata imx25_imx31_imx35_drvdata = {60	.nregs = 3 * 32,61};62 63static struct imx_iim_drvdata imx51_drvdata = {64	.nregs = 4 * 32,65};66 67static struct imx_iim_drvdata imx53_drvdata = {68	.nregs = 4 * 32 + 16,69};70 71static const struct of_device_id imx_iim_dt_ids[] = {72	{73		.compatible = "fsl,imx25-iim",74		.data = &imx25_imx31_imx35_drvdata,75	}, {76		.compatible = "fsl,imx27-iim",77		.data = &imx27_drvdata,78	}, {79		.compatible = "fsl,imx31-iim",80		.data = &imx25_imx31_imx35_drvdata,81	}, {82		.compatible = "fsl,imx35-iim",83		.data = &imx25_imx31_imx35_drvdata,84	}, {85		.compatible = "fsl,imx51-iim",86		.data = &imx51_drvdata,87	}, {88		.compatible = "fsl,imx53-iim",89		.data = &imx53_drvdata,90	}, {91		/* sentinel */92	},93};94MODULE_DEVICE_TABLE(of, imx_iim_dt_ids);95 96static int imx_iim_probe(struct platform_device *pdev)97{98	struct device *dev = &pdev->dev;99	struct iim_priv *iim;100	struct nvmem_device *nvmem;101	struct nvmem_config cfg = {};102	const struct imx_iim_drvdata *drvdata = NULL;103 104	iim = devm_kzalloc(dev, sizeof(*iim), GFP_KERNEL);105	if (!iim)106		return -ENOMEM;107 108	iim->base = devm_platform_ioremap_resource(pdev, 0);109	if (IS_ERR(iim->base))110		return PTR_ERR(iim->base);111 112	drvdata = of_device_get_match_data(&pdev->dev);113 114	iim->clk = devm_clk_get(dev, NULL);115	if (IS_ERR(iim->clk))116		return PTR_ERR(iim->clk);117 118	cfg.name = "imx-iim",119	cfg.read_only = true,120	cfg.word_size = 1,121	cfg.stride = 1,122	cfg.reg_read = imx_iim_read,123	cfg.dev = dev;124	cfg.size = drvdata->nregs;125	cfg.priv = iim;126 127	nvmem = devm_nvmem_register(dev, &cfg);128 129	return PTR_ERR_OR_ZERO(nvmem);130}131 132static struct platform_driver imx_iim_driver = {133	.probe	= imx_iim_probe,134	.driver = {135		.name	= "imx-iim",136		.of_match_table = imx_iim_dt_ids,137	},138};139module_platform_driver(imx_iim_driver);140 141MODULE_AUTHOR("Michael Grzeschik <m.grzeschik@pengutronix.de>");142MODULE_DESCRIPTION("i.MX IIM driver");143MODULE_LICENSE("GPL v2");144