4 * Copyright (c) 2017 Pengutronix, Michael Grzeschik <m.grzeschik@pengutronix.de>
6 * Based on the barebox iim driver,
7 * Copyright (c) 2010 Baruch Siach <baruch@tkos.co.il>,
8 * Orex Computed Radiography
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * http://www.opensource.org/licenses/gpl-license.html
15 * http://www.gnu.org/copyleft/gpl.html
18 #include <linux/device.h>
20 #include <linux/module.h>
21 #include <linux/nvmem-provider.h>
23 #include <linux/of_device.h>
24 #include <linux/platform_device.h>
25 #include <linux/slab.h>
26 #include <linux/clk.h>
28 #define IIM_BANK_BASE(n) (0x800 + 0x400 * (n))
30 struct imx_iim_drvdata
{
37 struct nvmem_config nvmem
;
40 static int imx_iim_read(void *context
, unsigned int offset
,
41 void *buf
, size_t bytes
)
43 struct iim_priv
*iim
= context
;
47 ret
= clk_prepare_enable(iim
->clk
);
51 for (i
= offset
; i
< offset
+ bytes
; i
++) {
55 *buf8
++ = readl(iim
->base
+ IIM_BANK_BASE(bank
) + reg
* 4);
58 clk_disable_unprepare(iim
->clk
);
63 static struct imx_iim_drvdata imx27_drvdata
= {
67 static struct imx_iim_drvdata imx25_imx31_imx35_drvdata
= {
71 static struct imx_iim_drvdata imx51_drvdata
= {
75 static struct imx_iim_drvdata imx53_drvdata
= {
79 static const struct of_device_id imx_iim_dt_ids
[] = {
81 .compatible
= "fsl,imx25-iim",
82 .data
= &imx25_imx31_imx35_drvdata
,
84 .compatible
= "fsl,imx27-iim",
85 .data
= &imx27_drvdata
,
87 .compatible
= "fsl,imx31-iim",
88 .data
= &imx25_imx31_imx35_drvdata
,
90 .compatible
= "fsl,imx35-iim",
91 .data
= &imx25_imx31_imx35_drvdata
,
93 .compatible
= "fsl,imx51-iim",
94 .data
= &imx51_drvdata
,
96 .compatible
= "fsl,imx53-iim",
97 .data
= &imx53_drvdata
,
102 MODULE_DEVICE_TABLE(of
, imx_iim_dt_ids
);
104 static int imx_iim_probe(struct platform_device
*pdev
)
106 const struct of_device_id
*of_id
;
107 struct device
*dev
= &pdev
->dev
;
108 struct resource
*res
;
109 struct iim_priv
*iim
;
110 struct nvmem_device
*nvmem
;
111 struct nvmem_config
*cfg
;
112 const struct imx_iim_drvdata
*drvdata
= NULL
;
114 iim
= devm_kzalloc(dev
, sizeof(*iim
), GFP_KERNEL
);
118 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
119 iim
->base
= devm_ioremap_resource(dev
, res
);
120 if (IS_ERR(iim
->base
))
121 return PTR_ERR(iim
->base
);
123 of_id
= of_match_device(imx_iim_dt_ids
, dev
);
127 drvdata
= of_id
->data
;
129 iim
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
130 if (IS_ERR(iim
->clk
))
131 return PTR_ERR(iim
->clk
);
135 cfg
->name
= "imx-iim",
136 cfg
->read_only
= true,
139 cfg
->owner
= THIS_MODULE
,
140 cfg
->reg_read
= imx_iim_read
,
142 cfg
->size
= drvdata
->nregs
;
145 nvmem
= nvmem_register(cfg
);
147 return PTR_ERR(nvmem
);
149 platform_set_drvdata(pdev
, nvmem
);
154 static int imx_iim_remove(struct platform_device
*pdev
)
156 struct nvmem_device
*nvmem
= platform_get_drvdata(pdev
);
158 return nvmem_unregister(nvmem
);
161 static struct platform_driver imx_iim_driver
= {
162 .probe
= imx_iim_probe
,
163 .remove
= imx_iim_remove
,
166 .of_match_table
= imx_iim_dt_ids
,
169 module_platform_driver(imx_iim_driver
);
171 MODULE_AUTHOR("Michael Grzeschik <m.grzeschik@pengutronix.de>");
172 MODULE_DESCRIPTION("i.MX IIM driver");
173 MODULE_LICENSE("GPL v2");