xref: /linux/drivers/nvmem/lpc18xx_eeprom.c (revision cbae17630954cb89f2bdf5bbadfd3aa81ea67283)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * NXP LPC18xx/LPC43xx EEPROM memory NVMEM driver
4  *
5  * Copyright (c) 2015 Ariel D'Alessandro <ariel@vanguardiasur.com>
6  */
7 
8 #include <linux/clk.h>
9 #include <linux/device.h>
10 #include <linux/delay.h>
11 #include <linux/err.h>
12 #include <linux/io.h>
13 #include <linux/module.h>
14 #include <linux/nvmem-provider.h>
15 #include <linux/platform_device.h>
16 #include <linux/reset.h>
17 
18 /* Registers */
19 #define LPC18XX_EEPROM_AUTOPROG			0x00c
20 #define LPC18XX_EEPROM_AUTOPROG_WORD		0x1
21 
22 #define LPC18XX_EEPROM_CLKDIV			0x014
23 
24 #define LPC18XX_EEPROM_PWRDWN			0x018
25 #define LPC18XX_EEPROM_PWRDWN_NO		0x0
26 #define LPC18XX_EEPROM_PWRDWN_YES		0x1
27 
28 #define LPC18XX_EEPROM_INTSTAT			0xfe0
29 #define LPC18XX_EEPROM_INTSTAT_END_OF_PROG	BIT(2)
30 
31 #define LPC18XX_EEPROM_INTSTATCLR		0xfe8
32 #define LPC18XX_EEPROM_INTSTATCLR_PROG_CLR_ST	BIT(2)
33 
34 /* Fixed page size (bytes) */
35 #define LPC18XX_EEPROM_PAGE_SIZE		0x80
36 
37 /* EEPROM device requires a ~1500 kHz clock (min 800 kHz, max 1600 kHz) */
38 #define LPC18XX_EEPROM_CLOCK_HZ			1500000
39 
40 /* EEPROM requires 3 ms of erase/program time between each writing */
41 #define LPC18XX_EEPROM_PROGRAM_TIME		3
42 
43 struct lpc18xx_eeprom_dev {
44 	struct clk *clk;
45 	void __iomem *reg_base;
46 	void __iomem *mem_base;
47 	struct nvmem_device *nvmem;
48 	unsigned reg_bytes;
49 	unsigned val_bytes;
50 	int size;
51 };
52 
53 static inline void lpc18xx_eeprom_writel(struct lpc18xx_eeprom_dev *eeprom,
54 					 u32 reg, u32 val)
55 {
56 	writel(val, eeprom->reg_base + reg);
57 }
58 
59 static inline u32 lpc18xx_eeprom_readl(struct lpc18xx_eeprom_dev *eeprom,
60 				       u32 reg)
61 {
62 	return readl(eeprom->reg_base + reg);
63 }
64 
65 static int lpc18xx_eeprom_busywait_until_prog(struct lpc18xx_eeprom_dev *eeprom)
66 {
67 	unsigned long end;
68 	u32 val;
69 
70 	/* Wait until EEPROM program operation has finished */
71 	end = jiffies + msecs_to_jiffies(LPC18XX_EEPROM_PROGRAM_TIME * 10);
72 
73 	while (time_is_after_jiffies(end)) {
74 		val = lpc18xx_eeprom_readl(eeprom, LPC18XX_EEPROM_INTSTAT);
75 
76 		if (val & LPC18XX_EEPROM_INTSTAT_END_OF_PROG) {
77 			lpc18xx_eeprom_writel(eeprom, LPC18XX_EEPROM_INTSTATCLR,
78 					LPC18XX_EEPROM_INTSTATCLR_PROG_CLR_ST);
79 			return 0;
80 		}
81 
82 		usleep_range(LPC18XX_EEPROM_PROGRAM_TIME * USEC_PER_MSEC,
83 			     (LPC18XX_EEPROM_PROGRAM_TIME + 1) * USEC_PER_MSEC);
84 	}
85 
86 	return -ETIMEDOUT;
87 }
88 
89 static int lpc18xx_eeprom_gather_write(void *context, unsigned int reg,
90 				       void *val, size_t bytes)
91 {
92 	struct lpc18xx_eeprom_dev *eeprom = context;
93 	unsigned int offset = reg;
94 	int ret;
95 
96 	/*
97 	 * The last page contains the EEPROM initialization data and is not
98 	 * writable.
99 	 */
100 	if ((reg > eeprom->size - LPC18XX_EEPROM_PAGE_SIZE) ||
101 			(reg + bytes > eeprom->size - LPC18XX_EEPROM_PAGE_SIZE))
102 		return -EINVAL;
103 
104 
105 	lpc18xx_eeprom_writel(eeprom, LPC18XX_EEPROM_PWRDWN,
106 			      LPC18XX_EEPROM_PWRDWN_NO);
107 
108 	/* Wait 100 us while the EEPROM wakes up */
109 	usleep_range(100, 200);
110 
111 	while (bytes) {
112 		writel(*(u32 *)val, eeprom->mem_base + offset);
113 		ret = lpc18xx_eeprom_busywait_until_prog(eeprom);
114 		if (ret < 0)
115 			return ret;
116 
117 		bytes -= eeprom->val_bytes;
118 		val += eeprom->val_bytes;
119 		offset += eeprom->val_bytes;
120 	}
121 
122 	lpc18xx_eeprom_writel(eeprom, LPC18XX_EEPROM_PWRDWN,
123 			      LPC18XX_EEPROM_PWRDWN_YES);
124 
125 	return 0;
126 }
127 
128 static int lpc18xx_eeprom_read(void *context, unsigned int offset,
129 			       void *val, size_t bytes)
130 {
131 	struct lpc18xx_eeprom_dev *eeprom = context;
132 
133 	lpc18xx_eeprom_writel(eeprom, LPC18XX_EEPROM_PWRDWN,
134 			      LPC18XX_EEPROM_PWRDWN_NO);
135 
136 	/* Wait 100 us while the EEPROM wakes up */
137 	usleep_range(100, 200);
138 
139 	while (bytes) {
140 		*(u32 *)val = readl(eeprom->mem_base + offset);
141 		bytes -= eeprom->val_bytes;
142 		val += eeprom->val_bytes;
143 		offset += eeprom->val_bytes;
144 	}
145 
146 	lpc18xx_eeprom_writel(eeprom, LPC18XX_EEPROM_PWRDWN,
147 			      LPC18XX_EEPROM_PWRDWN_YES);
148 
149 	return 0;
150 }
151 
152 
153 static struct nvmem_config lpc18xx_nvmem_config = {
154 	.name = "lpc18xx-eeprom",
155 	.stride = 4,
156 	.word_size = 4,
157 	.reg_read = lpc18xx_eeprom_read,
158 	.reg_write = lpc18xx_eeprom_gather_write,
159 };
160 
161 static int lpc18xx_eeprom_probe(struct platform_device *pdev)
162 {
163 	struct lpc18xx_eeprom_dev *eeprom;
164 	struct device *dev = &pdev->dev;
165 	struct reset_control *rst;
166 	unsigned long clk_rate;
167 	struct resource *res;
168 	int ret;
169 
170 	eeprom = devm_kzalloc(dev, sizeof(*eeprom), GFP_KERNEL);
171 	if (!eeprom)
172 		return -ENOMEM;
173 
174 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg");
175 	eeprom->reg_base = devm_ioremap_resource(dev, res);
176 	if (IS_ERR(eeprom->reg_base))
177 		return PTR_ERR(eeprom->reg_base);
178 
179 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem");
180 	eeprom->mem_base = devm_ioremap_resource(dev, res);
181 	if (IS_ERR(eeprom->mem_base))
182 		return PTR_ERR(eeprom->mem_base);
183 
184 	eeprom->clk = devm_clk_get(&pdev->dev, "eeprom");
185 	if (IS_ERR(eeprom->clk)) {
186 		dev_err(&pdev->dev, "failed to get eeprom clock\n");
187 		return PTR_ERR(eeprom->clk);
188 	}
189 
190 	ret = clk_prepare_enable(eeprom->clk);
191 	if (ret < 0) {
192 		dev_err(dev, "failed to prepare/enable eeprom clk: %d\n", ret);
193 		return ret;
194 	}
195 
196 	rst = devm_reset_control_get_exclusive(dev, NULL);
197 	if (IS_ERR(rst)) {
198 		dev_err(dev, "failed to get reset: %ld\n", PTR_ERR(rst));
199 		ret = PTR_ERR(rst);
200 		goto err_clk;
201 	}
202 
203 	ret = reset_control_assert(rst);
204 	if (ret < 0) {
205 		dev_err(dev, "failed to assert reset: %d\n", ret);
206 		goto err_clk;
207 	}
208 
209 	eeprom->val_bytes = 4;
210 	eeprom->reg_bytes = 4;
211 
212 	/*
213 	 * Clock rate is generated by dividing the system bus clock by the
214 	 * division factor, contained in the divider register (minus 1 encoded).
215 	 */
216 	clk_rate = clk_get_rate(eeprom->clk);
217 	clk_rate = DIV_ROUND_UP(clk_rate, LPC18XX_EEPROM_CLOCK_HZ) - 1;
218 	lpc18xx_eeprom_writel(eeprom, LPC18XX_EEPROM_CLKDIV, clk_rate);
219 
220 	/*
221 	 * Writing a single word to the page will start the erase/program cycle
222 	 * automatically
223 	 */
224 	lpc18xx_eeprom_writel(eeprom, LPC18XX_EEPROM_AUTOPROG,
225 			      LPC18XX_EEPROM_AUTOPROG_WORD);
226 
227 	lpc18xx_eeprom_writel(eeprom, LPC18XX_EEPROM_PWRDWN,
228 			      LPC18XX_EEPROM_PWRDWN_YES);
229 
230 	eeprom->size = resource_size(res);
231 	lpc18xx_nvmem_config.size = resource_size(res);
232 	lpc18xx_nvmem_config.dev = dev;
233 	lpc18xx_nvmem_config.priv = eeprom;
234 
235 	eeprom->nvmem = devm_nvmem_register(dev, &lpc18xx_nvmem_config);
236 	if (IS_ERR(eeprom->nvmem)) {
237 		ret = PTR_ERR(eeprom->nvmem);
238 		goto err_clk;
239 	}
240 
241 	platform_set_drvdata(pdev, eeprom);
242 
243 	return 0;
244 
245 err_clk:
246 	clk_disable_unprepare(eeprom->clk);
247 
248 	return ret;
249 }
250 
251 static void lpc18xx_eeprom_remove(struct platform_device *pdev)
252 {
253 	struct lpc18xx_eeprom_dev *eeprom = platform_get_drvdata(pdev);
254 
255 	clk_disable_unprepare(eeprom->clk);
256 }
257 
258 static const struct of_device_id lpc18xx_eeprom_of_match[] = {
259 	{ .compatible = "nxp,lpc1857-eeprom" },
260 	{ },
261 };
262 MODULE_DEVICE_TABLE(of, lpc18xx_eeprom_of_match);
263 
264 static struct platform_driver lpc18xx_eeprom_driver = {
265 	.probe = lpc18xx_eeprom_probe,
266 	.remove = lpc18xx_eeprom_remove,
267 	.driver = {
268 		.name = "lpc18xx-eeprom",
269 		.of_match_table = lpc18xx_eeprom_of_match,
270 	},
271 };
272 
273 module_platform_driver(lpc18xx_eeprom_driver);
274 
275 MODULE_AUTHOR("Ariel D'Alessandro <ariel@vanguardiasur.com.ar>");
276 MODULE_DESCRIPTION("NXP LPC18xx EEPROM memory Driver");
277 MODULE_LICENSE("GPL v2");
278