1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (c) 2017 Pengutronix, Michael Grzeschik <m.grzeschik@pengutronix.de>
7 * Based on the barebox iim driver,
8 * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>,
9 * Orex Computed Radiography
12 #include <linux/device.h>
14 #include <linux/module.h>
15 #include <linux/nvmem-provider.h>
17 #include <linux/of_device.h>
18 #include <linux/platform_device.h>
19 #include <linux/slab.h>
20 #include <linux/clk.h>
22 #define IIM_BANK_BASE(n) (0x800 + 0x400 * (n))
24 struct imx_iim_drvdata
{
33 static int imx_iim_read(void *context
, unsigned int offset
,
34 void *buf
, size_t bytes
)
36 struct iim_priv
*iim
= context
;
40 ret
= clk_prepare_enable(iim
->clk
);
44 for (i
= offset
; i
< offset
+ bytes
; i
++) {
48 *buf8
++ = readl(iim
->base
+ IIM_BANK_BASE(bank
) + reg
* 4);
51 clk_disable_unprepare(iim
->clk
);
56 static struct imx_iim_drvdata imx27_drvdata
= {
60 static struct imx_iim_drvdata imx25_imx31_imx35_drvdata
= {
64 static struct imx_iim_drvdata imx51_drvdata
= {
68 static struct imx_iim_drvdata imx53_drvdata
= {
72 static const struct of_device_id imx_iim_dt_ids
[] = {
74 .compatible
= "fsl,imx25-iim",
75 .data
= &imx25_imx31_imx35_drvdata
,
77 .compatible
= "fsl,imx27-iim",
78 .data
= &imx27_drvdata
,
80 .compatible
= "fsl,imx31-iim",
81 .data
= &imx25_imx31_imx35_drvdata
,
83 .compatible
= "fsl,imx35-iim",
84 .data
= &imx25_imx31_imx35_drvdata
,
86 .compatible
= "fsl,imx51-iim",
87 .data
= &imx51_drvdata
,
89 .compatible
= "fsl,imx53-iim",
90 .data
= &imx53_drvdata
,
95 MODULE_DEVICE_TABLE(of
, imx_iim_dt_ids
);
97 static int imx_iim_probe(struct platform_device
*pdev
)
99 const struct of_device_id
*of_id
;
100 struct device
*dev
= &pdev
->dev
;
101 struct iim_priv
*iim
;
102 struct nvmem_device
*nvmem
;
103 struct nvmem_config cfg
= {};
104 const struct imx_iim_drvdata
*drvdata
= NULL
;
106 iim
= devm_kzalloc(dev
, sizeof(*iim
), GFP_KERNEL
);
110 iim
->base
= devm_platform_ioremap_resource(pdev
, 0);
111 if (IS_ERR(iim
->base
))
112 return PTR_ERR(iim
->base
);
114 of_id
= of_match_device(imx_iim_dt_ids
, dev
);
118 drvdata
= of_id
->data
;
120 iim
->clk
= devm_clk_get(dev
, NULL
);
121 if (IS_ERR(iim
->clk
))
122 return PTR_ERR(iim
->clk
);
124 cfg
.name
= "imx-iim",
125 cfg
.read_only
= true,
128 cfg
.reg_read
= imx_iim_read
,
130 cfg
.size
= drvdata
->nregs
;
133 nvmem
= devm_nvmem_register(dev
, &cfg
);
135 return PTR_ERR_OR_ZERO(nvmem
);
138 static struct platform_driver imx_iim_driver
= {
139 .probe
= imx_iim_probe
,
142 .of_match_table
= imx_iim_dt_ids
,
145 module_platform_driver(imx_iim_driver
);
147 MODULE_AUTHOR("Michael Grzeschik <m.grzeschik@pengutronix.de>");
148 MODULE_DESCRIPTION("i.MX IIM driver");
149 MODULE_LICENSE("GPL v2");