xref: /openbmc/linux/drivers/w1/slaves/w1_ds28e04.c (revision 0317cd52)
1 /*
2  *	w1_ds28e04.c - w1 family 1C (DS28E04) driver
3  *
4  * Copyright (c) 2012 Markus Franke <franke.m@sebakmt.com>
5  *
6  * This source code is licensed under the GNU General Public License,
7  * Version 2. See the file COPYING for more details.
8  */
9 
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/moduleparam.h>
13 #include <linux/device.h>
14 #include <linux/types.h>
15 #include <linux/delay.h>
16 #include <linux/slab.h>
17 #include <linux/crc16.h>
18 #include <linux/uaccess.h>
19 
20 #define CRC16_INIT		0
21 #define CRC16_VALID		0xb001
22 
23 #include "../w1.h"
24 #include "../w1_int.h"
25 #include "../w1_family.h"
26 
27 MODULE_LICENSE("GPL");
28 MODULE_AUTHOR("Markus Franke <franke.m@sebakmt.com>, <franm@hrz.tu-chemnitz.de>");
29 MODULE_DESCRIPTION("w1 family 1C driver for DS28E04, 4kb EEPROM and PIO");
30 MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS28E04));
31 
32 /* Allow the strong pullup to be disabled, but default to enabled.
33  * If it was disabled a parasite powered device might not get the required
34  * current to copy the data from the scratchpad to EEPROM.  If it is enabled
35  * parasite powered devices have a better chance of getting the current
36  * required.
37  */
38 static int w1_strong_pullup = 1;
39 module_param_named(strong_pullup, w1_strong_pullup, int, 0);
40 
41 /* enable/disable CRC checking on DS28E04-100 memory accesses */
42 static char w1_enable_crccheck = 1;
43 
44 #define W1_EEPROM_SIZE		512
45 #define W1_PAGE_COUNT		16
46 #define W1_PAGE_SIZE		32
47 #define W1_PAGE_BITS		5
48 #define W1_PAGE_MASK		0x1F
49 
50 #define W1_F1C_READ_EEPROM	0xF0
51 #define W1_F1C_WRITE_SCRATCH	0x0F
52 #define W1_F1C_READ_SCRATCH	0xAA
53 #define W1_F1C_COPY_SCRATCH	0x55
54 #define W1_F1C_ACCESS_WRITE	0x5A
55 
56 #define W1_1C_REG_LOGIC_STATE	0x220
57 
58 struct w1_f1C_data {
59 	u8	memory[W1_EEPROM_SIZE];
60 	u32	validcrc;
61 };
62 
63 /**
64  * Check the file size bounds and adjusts count as needed.
65  * This would not be needed if the file size didn't reset to 0 after a write.
66  */
67 static inline size_t w1_f1C_fix_count(loff_t off, size_t count, size_t size)
68 {
69 	if (off > size)
70 		return 0;
71 
72 	if ((off + count) > size)
73 		return size - off;
74 
75 	return count;
76 }
77 
78 static int w1_f1C_refresh_block(struct w1_slave *sl, struct w1_f1C_data *data,
79 				int block)
80 {
81 	u8	wrbuf[3];
82 	int	off = block * W1_PAGE_SIZE;
83 
84 	if (data->validcrc & (1 << block))
85 		return 0;
86 
87 	if (w1_reset_select_slave(sl)) {
88 		data->validcrc = 0;
89 		return -EIO;
90 	}
91 
92 	wrbuf[0] = W1_F1C_READ_EEPROM;
93 	wrbuf[1] = off & 0xff;
94 	wrbuf[2] = off >> 8;
95 	w1_write_block(sl->master, wrbuf, 3);
96 	w1_read_block(sl->master, &data->memory[off], W1_PAGE_SIZE);
97 
98 	/* cache the block if the CRC is valid */
99 	if (crc16(CRC16_INIT, &data->memory[off], W1_PAGE_SIZE) == CRC16_VALID)
100 		data->validcrc |= (1 << block);
101 
102 	return 0;
103 }
104 
105 static int w1_f1C_read(struct w1_slave *sl, int addr, int len, char *data)
106 {
107 	u8 wrbuf[3];
108 
109 	/* read directly from the EEPROM */
110 	if (w1_reset_select_slave(sl))
111 		return -EIO;
112 
113 	wrbuf[0] = W1_F1C_READ_EEPROM;
114 	wrbuf[1] = addr & 0xff;
115 	wrbuf[2] = addr >> 8;
116 
117 	w1_write_block(sl->master, wrbuf, sizeof(wrbuf));
118 	return w1_read_block(sl->master, data, len);
119 }
120 
121 static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
122 			   struct bin_attribute *bin_attr, char *buf,
123 			   loff_t off, size_t count)
124 {
125 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
126 	struct w1_f1C_data *data = sl->family_data;
127 	int i, min_page, max_page;
128 
129 	count = w1_f1C_fix_count(off, count, W1_EEPROM_SIZE);
130 	if (count == 0)
131 		return 0;
132 
133 	mutex_lock(&sl->master->mutex);
134 
135 	if (w1_enable_crccheck) {
136 		min_page = (off >> W1_PAGE_BITS);
137 		max_page = (off + count - 1) >> W1_PAGE_BITS;
138 		for (i = min_page; i <= max_page; i++) {
139 			if (w1_f1C_refresh_block(sl, data, i)) {
140 				count = -EIO;
141 				goto out_up;
142 			}
143 		}
144 		memcpy(buf, &data->memory[off], count);
145 	} else {
146 		count = w1_f1C_read(sl, off, count, buf);
147 	}
148 
149 out_up:
150 	mutex_unlock(&sl->master->mutex);
151 
152 	return count;
153 }
154 
155 /**
156  * Writes to the scratchpad and reads it back for verification.
157  * Then copies the scratchpad to EEPROM.
158  * The data must be on one page.
159  * The master must be locked.
160  *
161  * @param sl	The slave structure
162  * @param addr	Address for the write
163  * @param len   length must be <= (W1_PAGE_SIZE - (addr & W1_PAGE_MASK))
164  * @param data	The data to write
165  * @return	0=Success -1=failure
166  */
167 static int w1_f1C_write(struct w1_slave *sl, int addr, int len, const u8 *data)
168 {
169 	u8 wrbuf[4];
170 	u8 rdbuf[W1_PAGE_SIZE + 3];
171 	u8 es = (addr + len - 1) & 0x1f;
172 	unsigned int tm = 10;
173 	int i;
174 	struct w1_f1C_data *f1C = sl->family_data;
175 
176 	/* Write the data to the scratchpad */
177 	if (w1_reset_select_slave(sl))
178 		return -1;
179 
180 	wrbuf[0] = W1_F1C_WRITE_SCRATCH;
181 	wrbuf[1] = addr & 0xff;
182 	wrbuf[2] = addr >> 8;
183 
184 	w1_write_block(sl->master, wrbuf, 3);
185 	w1_write_block(sl->master, data, len);
186 
187 	/* Read the scratchpad and verify */
188 	if (w1_reset_select_slave(sl))
189 		return -1;
190 
191 	w1_write_8(sl->master, W1_F1C_READ_SCRATCH);
192 	w1_read_block(sl->master, rdbuf, len + 3);
193 
194 	/* Compare what was read against the data written */
195 	if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) ||
196 	    (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0))
197 		return -1;
198 
199 	/* Copy the scratchpad to EEPROM */
200 	if (w1_reset_select_slave(sl))
201 		return -1;
202 
203 	wrbuf[0] = W1_F1C_COPY_SCRATCH;
204 	wrbuf[3] = es;
205 
206 	for (i = 0; i < sizeof(wrbuf); ++i) {
207 		/* issue 10ms strong pullup (or delay) on the last byte
208 		   for writing the data from the scratchpad to EEPROM */
209 		if (w1_strong_pullup && i == sizeof(wrbuf)-1)
210 			w1_next_pullup(sl->master, tm);
211 
212 		w1_write_8(sl->master, wrbuf[i]);
213 	}
214 
215 	if (!w1_strong_pullup)
216 		msleep(tm);
217 
218 	if (w1_enable_crccheck) {
219 		/* invalidate cached data */
220 		f1C->validcrc &= ~(1 << (addr >> W1_PAGE_BITS));
221 	}
222 
223 	/* Reset the bus to wake up the EEPROM (this may not be needed) */
224 	w1_reset_bus(sl->master);
225 
226 	return 0;
227 }
228 
229 static ssize_t eeprom_write(struct file *filp, struct kobject *kobj,
230 			    struct bin_attribute *bin_attr, char *buf,
231 			    loff_t off, size_t count)
232 
233 {
234 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
235 	int addr, len, idx;
236 
237 	count = w1_f1C_fix_count(off, count, W1_EEPROM_SIZE);
238 	if (count == 0)
239 		return 0;
240 
241 	if (w1_enable_crccheck) {
242 		/* can only write full blocks in cached mode */
243 		if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) {
244 			dev_err(&sl->dev, "invalid offset/count off=%d cnt=%zd\n",
245 				(int)off, count);
246 			return -EINVAL;
247 		}
248 
249 		/* make sure the block CRCs are valid */
250 		for (idx = 0; idx < count; idx += W1_PAGE_SIZE) {
251 			if (crc16(CRC16_INIT, &buf[idx], W1_PAGE_SIZE)
252 				!= CRC16_VALID) {
253 				dev_err(&sl->dev, "bad CRC at offset %d\n",
254 					(int)off);
255 				return -EINVAL;
256 			}
257 		}
258 	}
259 
260 	mutex_lock(&sl->master->mutex);
261 
262 	/* Can only write data to one page at a time */
263 	idx = 0;
264 	while (idx < count) {
265 		addr = off + idx;
266 		len = W1_PAGE_SIZE - (addr & W1_PAGE_MASK);
267 		if (len > (count - idx))
268 			len = count - idx;
269 
270 		if (w1_f1C_write(sl, addr, len, &buf[idx]) < 0) {
271 			count = -EIO;
272 			goto out_up;
273 		}
274 		idx += len;
275 	}
276 
277 out_up:
278 	mutex_unlock(&sl->master->mutex);
279 
280 	return count;
281 }
282 
283 static BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE);
284 
285 static ssize_t pio_read(struct file *filp, struct kobject *kobj,
286 			struct bin_attribute *bin_attr, char *buf, loff_t off,
287 			size_t count)
288 
289 {
290 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
291 	int ret;
292 
293 	/* check arguments */
294 	if (off != 0 || count != 1 || buf == NULL)
295 		return -EINVAL;
296 
297 	mutex_lock(&sl->master->mutex);
298 	ret = w1_f1C_read(sl, W1_1C_REG_LOGIC_STATE, count, buf);
299 	mutex_unlock(&sl->master->mutex);
300 
301 	return ret;
302 }
303 
304 static ssize_t pio_write(struct file *filp, struct kobject *kobj,
305 			 struct bin_attribute *bin_attr, char *buf, loff_t off,
306 			 size_t count)
307 
308 {
309 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
310 	u8 wrbuf[3];
311 	u8 ack;
312 
313 	/* check arguments */
314 	if (off != 0 || count != 1 || buf == NULL)
315 		return -EINVAL;
316 
317 	mutex_lock(&sl->master->mutex);
318 
319 	/* Write the PIO data */
320 	if (w1_reset_select_slave(sl)) {
321 		mutex_unlock(&sl->master->mutex);
322 		return -1;
323 	}
324 
325 	/* set bit 7..2 to value '1' */
326 	*buf = *buf | 0xFC;
327 
328 	wrbuf[0] = W1_F1C_ACCESS_WRITE;
329 	wrbuf[1] = *buf;
330 	wrbuf[2] = ~(*buf);
331 	w1_write_block(sl->master, wrbuf, 3);
332 
333 	w1_read_block(sl->master, &ack, sizeof(ack));
334 
335 	mutex_unlock(&sl->master->mutex);
336 
337 	/* check for acknowledgement */
338 	if (ack != 0xAA)
339 		return -EIO;
340 
341 	return count;
342 }
343 
344 static BIN_ATTR_RW(pio, 1);
345 
346 static ssize_t crccheck_show(struct device *dev, struct device_attribute *attr,
347 			     char *buf)
348 {
349 	if (put_user(w1_enable_crccheck + 0x30, buf))
350 		return -EFAULT;
351 
352 	return sizeof(w1_enable_crccheck);
353 }
354 
355 static ssize_t crccheck_store(struct device *dev, struct device_attribute *attr,
356 			      const char *buf, size_t count)
357 {
358 	char val;
359 
360 	if (count != 1 || !buf)
361 		return -EINVAL;
362 
363 	if (get_user(val, buf))
364 		return -EFAULT;
365 
366 	/* convert to decimal */
367 	val = val - 0x30;
368 	if (val != 0 && val != 1)
369 		return -EINVAL;
370 
371 	/* set the new value */
372 	w1_enable_crccheck = val;
373 
374 	return sizeof(w1_enable_crccheck);
375 }
376 
377 static DEVICE_ATTR_RW(crccheck);
378 
379 static struct attribute *w1_f1C_attrs[] = {
380 	&dev_attr_crccheck.attr,
381 	NULL,
382 };
383 
384 static struct bin_attribute *w1_f1C_bin_attrs[] = {
385 	&bin_attr_eeprom,
386 	&bin_attr_pio,
387 	NULL,
388 };
389 
390 static const struct attribute_group w1_f1C_group = {
391 	.attrs		= w1_f1C_attrs,
392 	.bin_attrs	= w1_f1C_bin_attrs,
393 };
394 
395 static const struct attribute_group *w1_f1C_groups[] = {
396 	&w1_f1C_group,
397 	NULL,
398 };
399 
400 static int w1_f1C_add_slave(struct w1_slave *sl)
401 {
402 	struct w1_f1C_data *data = NULL;
403 
404 	if (w1_enable_crccheck) {
405 		data = kzalloc(sizeof(struct w1_f1C_data), GFP_KERNEL);
406 		if (!data)
407 			return -ENOMEM;
408 		sl->family_data = data;
409 	}
410 
411 	return 0;
412 }
413 
414 static void w1_f1C_remove_slave(struct w1_slave *sl)
415 {
416 	kfree(sl->family_data);
417 	sl->family_data = NULL;
418 }
419 
420 static struct w1_family_ops w1_f1C_fops = {
421 	.add_slave      = w1_f1C_add_slave,
422 	.remove_slave   = w1_f1C_remove_slave,
423 	.groups		= w1_f1C_groups,
424 };
425 
426 static struct w1_family w1_family_1C = {
427 	.fid = W1_FAMILY_DS28E04,
428 	.fops = &w1_f1C_fops,
429 };
430 module_w1_family(w1_family_1C);
431