xref: /linux/drivers/w1/slaves/w1_ds28e04.c (revision ff5599816711d2e67da2d7561fd36ac48debd433)
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 w1_f1C_read_bin(struct file *filp, struct kobject *kobj,
122 			       struct bin_attribute *bin_attr,
123 			       char *buf, 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 w1_f1C_write_bin(struct file *filp, struct kobject *kobj,
230 			       struct bin_attribute *bin_attr,
231 			       char *buf, 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 ssize_t w1_f1C_read_pio(struct file *filp, struct kobject *kobj,
284 			       struct bin_attribute *bin_attr,
285 			       char *buf, loff_t off, size_t count)
286 
287 {
288 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
289 	int ret;
290 
291 	/* check arguments */
292 	if (off != 0 || count != 1 || buf == NULL)
293 		return -EINVAL;
294 
295 	mutex_lock(&sl->master->mutex);
296 	ret = w1_f1C_read(sl, W1_1C_REG_LOGIC_STATE, count, buf);
297 	mutex_unlock(&sl->master->mutex);
298 
299 	return ret;
300 }
301 
302 static ssize_t w1_f1C_write_pio(struct file *filp, struct kobject *kobj,
303 				struct bin_attribute *bin_attr,
304 				char *buf, loff_t off, size_t count)
305 
306 {
307 	struct w1_slave *sl = kobj_to_w1_slave(kobj);
308 	u8 wrbuf[3];
309 	u8 ack;
310 
311 	/* check arguments */
312 	if (off != 0 || count != 1 || buf == NULL)
313 		return -EINVAL;
314 
315 	mutex_lock(&sl->master->mutex);
316 
317 	/* Write the PIO data */
318 	if (w1_reset_select_slave(sl)) {
319 		mutex_unlock(&sl->master->mutex);
320 		return -1;
321 	}
322 
323 	/* set bit 7..2 to value '1' */
324 	*buf = *buf | 0xFC;
325 
326 	wrbuf[0] = W1_F1C_ACCESS_WRITE;
327 	wrbuf[1] = *buf;
328 	wrbuf[2] = ~(*buf);
329 	w1_write_block(sl->master, wrbuf, 3);
330 
331 	w1_read_block(sl->master, &ack, sizeof(ack));
332 
333 	mutex_unlock(&sl->master->mutex);
334 
335 	/* check for acknowledgement */
336 	if (ack != 0xAA)
337 		return -EIO;
338 
339 	return count;
340 }
341 
342 static ssize_t w1_f1C_show_crccheck(struct device *dev,
343 				    struct device_attribute *attr, char *buf)
344 {
345 	if (put_user(w1_enable_crccheck + 0x30, buf))
346 		return -EFAULT;
347 
348 	return sizeof(w1_enable_crccheck);
349 }
350 
351 static ssize_t w1_f1C_store_crccheck(struct device *dev,
352 				     struct device_attribute *attr,
353 				     const char *buf, size_t count)
354 {
355 	char val;
356 
357 	if (count != 1 || !buf)
358 		return -EINVAL;
359 
360 	if (get_user(val, buf))
361 		return -EFAULT;
362 
363 	/* convert to decimal */
364 	val = val - 0x30;
365 	if (val != 0 && val != 1)
366 		return -EINVAL;
367 
368 	/* set the new value */
369 	w1_enable_crccheck = val;
370 
371 	return sizeof(w1_enable_crccheck);
372 }
373 
374 #define NB_SYSFS_BIN_FILES 2
375 static struct bin_attribute w1_f1C_bin_attr[NB_SYSFS_BIN_FILES] = {
376 	{
377 		.attr = {
378 			.name = "eeprom",
379 			.mode = S_IRUGO | S_IWUSR,
380 		},
381 		.size = W1_EEPROM_SIZE,
382 		.read = w1_f1C_read_bin,
383 		.write = w1_f1C_write_bin,
384 	},
385 	{
386 		.attr = {
387 			.name = "pio",
388 			.mode = S_IRUGO | S_IWUSR,
389 		},
390 		.size = 1,
391 		.read = w1_f1C_read_pio,
392 		.write = w1_f1C_write_pio,
393 	}
394 };
395 
396 static DEVICE_ATTR(crccheck, S_IWUSR | S_IRUGO,
397 		   w1_f1C_show_crccheck, w1_f1C_store_crccheck);
398 
399 static int w1_f1C_add_slave(struct w1_slave *sl)
400 {
401 	int err = 0;
402 	int i;
403 	struct w1_f1C_data *data = NULL;
404 
405 	if (w1_enable_crccheck) {
406 		data = kzalloc(sizeof(struct w1_f1C_data), GFP_KERNEL);
407 		if (!data)
408 			return -ENOMEM;
409 		sl->family_data = data;
410 	}
411 
412 	/* create binary sysfs attributes */
413 	for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i)
414 		err = sysfs_create_bin_file(
415 			&sl->dev.kobj, &(w1_f1C_bin_attr[i]));
416 
417 	if (!err) {
418 		/* create device attributes */
419 		err = device_create_file(&sl->dev, &dev_attr_crccheck);
420 	}
421 
422 	if (err) {
423 		/* remove binary sysfs attributes */
424 		for (i = 0; i < NB_SYSFS_BIN_FILES; ++i)
425 			sysfs_remove_bin_file(
426 				&sl->dev.kobj, &(w1_f1C_bin_attr[i]));
427 
428 		kfree(data);
429 	}
430 
431 	return err;
432 }
433 
434 static void w1_f1C_remove_slave(struct w1_slave *sl)
435 {
436 	int i;
437 
438 	kfree(sl->family_data);
439 	sl->family_data = NULL;
440 
441 	/* remove device attributes */
442 	device_remove_file(&sl->dev, &dev_attr_crccheck);
443 
444 	/* remove binary sysfs attributes */
445 	for (i = 0; i < NB_SYSFS_BIN_FILES; ++i)
446 		sysfs_remove_bin_file(&sl->dev.kobj, &(w1_f1C_bin_attr[i]));
447 }
448 
449 static struct w1_family_ops w1_f1C_fops = {
450 	.add_slave      = w1_f1C_add_slave,
451 	.remove_slave   = w1_f1C_remove_slave,
452 };
453 
454 static struct w1_family w1_family_1C = {
455 	.fid = W1_FAMILY_DS28E04,
456 	.fops = &w1_f1C_fops,
457 };
458 
459 static int __init w1_f1C_init(void)
460 {
461 	return w1_register_family(&w1_family_1C);
462 }
463 
464 static void __exit w1_f1C_fini(void)
465 {
466 	w1_unregister_family(&w1_family_1C);
467 }
468 
469 module_init(w1_f1C_init);
470 module_exit(w1_f1C_fini);
471